我有一个非常简单的ASP.NET MVC 4控制器:
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: 在异步操作仍在进行的情况下完成了异步模块或处理程序。]
为什么会发生这种情况?我进行了一些测试:
- 如果我们从构造函数中删除
task = DownloadAsync();
并将其放入Index
方法,则可以正常工作而没有错误。 - 如果我们使用另一个
DownloadAsync()
主体return await Task.Factory.StartNew(() => { Thread.Sleep(3000); return "给我一个错误"; });
,它将正常工作。
为什么不能在控制器的构造函数中使用WebClient.DownloadStringTaskAsync
方法?
Task
,但它甚至不知道async void
,因此它将完成返回给ASP.NET Core,后者发现它实际上并没有完成。”控制器构造函数编译成void
方法,这就是我得到错误的原因。我是对的吗? - dyatchenkoDownloadStringTaskAsync
方法中获取结果的。我只是设置了一个断点来检查它。这并不意味着我是“异步”获取结果吗? - dyatchenkoawait Task.Delay(TimeSpan.FromSeconds(10))
,则其他任务将在当前线程上运行并有机会完成。但是,等待时间过去并不是解决方案,因为您的下载可能需要更长时间。正确的解决方案是在所有操作方法中放置await task
。 - binkiIndex()
中使用task = DownloadAsync();
调用时,异步操作似乎仍在进行中,直到Index()
完成。 - O. R. Mapper