我正在尝试理解为什么在ASP.Net应用程序中的异步void方法可能会导致以下异常,而异步任务似乎不会:
System.InvalidOperationException: An asynchronous module or handler
completed while an asynchronous operation was still pending
我对.NET中的异步世界相对较新,但我感觉已经通过多种现有资源(包括以下所有内容)尝试了解这个问题: 从这些资源中,我了解到最佳实践通常是返回Task并避免使用async void。我还知道,当调用该方法时,async 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;
}
}
另外,如果我对async void的理解正确的话,在这种情况下把async void当作“fire and forget”是不是有点错误,因为ASP.Net实际上并没有忘记它呢?