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