作者:mobiledu2502881447 | 来源:互联网 | 2023-02-01 20:35
如下所示的异步方法应在ASP.NET MVC网站中等待执行。
public async Task DoStaff()
{
// business logic here
}
我们找到了两种解决方案来完成此任务,并且都可以在我们的测试平台上工作:
解决方案1:
public void DoStaffWrapper()
{
DoStaff();
// clean up
}
public ActionResult Caller()
{
DoStaffWrapper();
// return blah blah blah;
}
解决方案2:
public async Task DoStaffWrapperAsync()
{
await DoStaff();
// clean up
}
public ActionResult Caller()
{
Task.Run(() => DoStaffWrapperAsync());
// return blah blah blah;
}
那么它们之间有什么区别呢?哪个更好,为什么?有什么好处吗?
1> Kevin Gosse..:
除非您可以精确控制IIS池的生命周期(或者除非您实际上不在IIS上运行),否则您应该使用它QueueBackgroundWorkItem
来启动即发即忘任务。它确保运行时能够跟踪它们,并且不会过早终止该过程。
HostingEnvironment.QueueBackgroundWorkItem(_ => DoStaff());
如果出于某种原因您不想使用或不需要此方法,则调用async方法的两种方法之间存在重要区别:
DoStaff()
将在当前线程上同步运行,直到await
找到一条语句为止,然后它将对该线程产生控制权(之后DoStaff
执行的任何操作都可以执行。此外,该方法将在ASP.NET的同步上下文中执行,因此您将如果您不使用.ConfigureAwait(false)
它来等待内部呼叫,则会遇到麻烦。
Task.Run(() => DoStaffWrapperAsync())
将完全异步运行,并在单独的上下文中运行(因此您不会遇到上述问题)。
简单来说,请采用以下方法:
public Task DoStaff()
{
Thread.Sleep(1000);
await AnotherMethodAsync();
Thread.Sleep(1000);
}
如果您呼叫DoStaff
,通话将阻塞一秒钟。如果您呼叫Task.Run(() => DoStaff())
,则呼叫将立即返回。但是,如果在第一次学习之前没有大量工作await
,那么您将无所适从地跳到新线程。