我有一個非常簡單的ASP.NET MVC 4控制器的異步模塊或處理程序:ASP.NET控制器:完成,而異步操作仍然懸而未決
public class HomeController : Controller
{
private const string MY_URL = "http://smthing";
private readonly Task<string> task;
public HomeController() { task = DownloadAsync(); }
public ActionResult Index() { return View(); }
private async Task<string> DownloadAsync()
{
using (WebClient myWebClient = new WebClient())
return await myWebClient.DownloadStringTaskAsync(MY_URL)
.ConfigureAwait(false);
}
}
當我開始的項目,我看到我的觀點和它看起來不錯,但當我更新頁面時,出現以下錯誤:
[InvalidOperationException: An asynchronous module or handler completed while an asynchronous operation was still pending.]
爲什麼會發生?我做了幾個測試:
- 如果我們從構造函數中刪除
task = DownloadAsync();
,並把它放入Index
方法它會正常工作沒有錯誤。 - 如果我們使用另一個
DownloadAsync()
機身return await Task.Factory.StartNew(() => { Thread.Sleep(3000); return "Give me an error"; });
它會正常工作。
爲什麼無法在控制器的構造函數中使用WebClient.DownloadStringTaskAsync
方法?
感謝您的回答。我已經閱讀過你提到的那篇文章,但我再讀一遍。我不知道爲什麼我以前沒有意識到它,但我的問題的關鍵應該是第二句話:「MVC框架了解如何等待您的」任務「,但它甚至不知道'async void',所以它向ASP.NET內核返回完成,它看到它實際上並沒有完成。「控制器的構造函數被編譯成'void'方法,這就是爲什麼我得到錯誤。我對嗎? – dyatchenko 2015-03-02 10:04:36
@dyatchenko號。這與'async void'無關。 ASP.NET知道如何處理'async Task'。因爲它註冊到'SynchronizationContext',它注意到你的'DownloadAsync'方法在你的控制器返回時沒有完成。 – 2015-03-02 10:05:55
好的。在這種情況下,正如你所提到的,我可以等幾秒鐘,而我的下載完成後,我可以刷新頁面,它應該沒問題,但事實並非如此。 – dyatchenko 2015-03-02 10:14:49