在我的ASP.NET MVC 4应用程序中,假设我有一些async
方法:
async Task DoSomeBackgroundWork()
{
// Fake it
await Task.Delay(5000);
}
现在,人们可以这样调用这个方法:
Task.Run(async () =>
{
await DoSomeBackgroundWork();
Debug.WriteLine("Background work finished");
});
或者这个:
DoSomeBackgroundWork()
.ContinueWith(t => Debug.WriteLine("Background work finished"));
请注意,在这两个版本中,调用者不会等待后台任务完成。这只是火和忘记。
虽然两个版本在常规.NET应用程序上相同(忽略异常处理),但在MVC应用程序上,从MVC控制器方法调用代码时,Debug.WriteLine
仅执行在Task.Run
版本中,但不在ContinueWith
版本中。
在MVC控制器方法中调用时,有没有人可以解释为什么这两个版本的工作方式不同?
答案 0 :(得分:5)
这可能是您的网络应用特有的,所以我只能推测,但这就是我的想法:
如果您这样做,它应该有效:
DoSomeBackgroundWork()
.ContinueWith(t => Debug.WriteLine("Background work finished"),
TaskContinuationOptions.ExecuteSynchronously);
这将更接近Task.Run
版本,其中延续同步运行。
在您直接从控制器方法调用DoSomeBackgroundWork
之前,请添加以下内容:
Debug.WriteLine(new { TaskScheduler.Current });
如果输出不是ThreadPoolTaskScheduler
,我可能会进一步解释这种行为(因为我刚刚处理了一个有点相关的问题here)。