Seb*_*ski 8 c# asp.net asp.net-mvc task-parallel-library async-await
在我的ASP.NET MVC 4应用程序中,假设我有一些async方法:
async Task DoSomeBackgroundWork()
{
// Fake it
await Task.Delay(5000);
}
Run Code Online (Sandbox Code Playgroud)
现在,可以像这样调用这个方法:
Task.Run(async () =>
{
await DoSomeBackgroundWork();
Debug.WriteLine("Background work finished");
});
Run Code Online (Sandbox Code Playgroud)
或这个:
DoSomeBackgroundWork()
.ContinueWith(t => Debug.WriteLine("Background work finished"));
Run Code Online (Sandbox Code Playgroud)
请注意,在两个版本中,调用者都不会等待后台任务完成.这只是火和忘记.
虽然两个版本在常规.NET应用程序上相同(忽略异常处理),但在MVC应用程序上,从MVC控制器方法调用代码时,Debug.WriteLine只在Task.Run版本中执行- 但不在ContinueWith版本中执行.
任何人都可以了解为什么这两个版本在MVC控制器方法中调用时的工作方式不同?
这可能是您的网络应用程序特有的,所以我只能推测,但这是我的想法:
它应该工作如果你这样做:
DoSomeBackgroundWork()
.ContinueWith(t => Debug.WriteLine("Background work finished"),
TaskContinuationOptions.ExecuteSynchronously);
Run Code Online (Sandbox Code Playgroud)
这将更接近于Task.Run版本,其中延续同步运行.
在您DoSomeBackgroundWork直接从控制器方法调用之前,添加以下内容:
Debug.WriteLine(new { TaskScheduler.Current });
Run Code Online (Sandbox Code Playgroud)
如果输出是什么,但ThreadPoolTaskScheduler,我也许可以进一步解释这种行为(因为我刚刚处理了一个有点相关的问题在这里).
顺便说一句,在ASP.NET中使用fire-and-forget这样做真的不是一个好主意,有很多关于SO讨论这个的问题.