我试图理解为什么在ASP中使用异步void方法.Net应用程序可能会导致以下异常,但异步任务似乎不会:
System.InvalidOperationException: An asynchronous module or handler
completed while an asynchronous operation was still pending
我对中国的异步世界还比较陌生.NET,但我确实觉得我已经try 通过大量现有资源来运行这一功能,包括以下所有资源:
- What's the difference between returning void and returning a Task?个
- It's All About the SynchronizationContext个
- Async Syntactic Sugar Suggestions个
- Async in ASP.NET
从这些资源中,我了解到最佳实践通常是返回Task并避免异步无效.我还理解异步void在调用方法时递增未完成操作的计数,在方法完成时递减.这听起来至少是我问题的部分答案.然而,我缺少的是当我返回Task时会发生什么,以及为什么这样做会使事情"正常工作".
下面是一个人为的例子来进一步说明我的问题:
public class HomeController : AsyncController
{
// This method will work fine
public async Task<ActionResult> ThisPageWillLoad()
{
// Do not await the task since it is meant to be fire and forget
var task = this.FireAndForgetTask();
return await Task.FromResult(this.View("Index"));
}
private async Task FireAndForgetTask()
{
var task = Task.Delay(TimeSpan.FromSeconds(3));
await task;
}
// This method will throw the following exception:
// System.InvalidOperationException: An asynchronous module or
// handler completed while an asynchronous operation was still pending
public async Task<ActionResult> ThisPageWillNotLoad()
{
// Obviously can't await a void method
this.FireAndForgetVoid();
return await Task.FromResult(this.View("Index"));
}
private async void FireAndForgetVoid()
{
var task = Task.Delay(TimeSpan.FromSeconds(3));
await task;
}
}
另外,如果我对异步void的理解是正确的,那么在这种情况下将async void视为"即发即忘"是不是有点错误,因为ASP.NET实际上并没有忘记这一点?