异步/等待和多层Web应用程序

时间:2015-04-01 09:58:39

标签: c# asp.net asynchronous async-await

由于一些优化问题,我决定将控制器的操作方法重写为异步操作方法。它是一个多层应用程序,从那时起,我面临一个架构问题,我想知道下面将展示两个approches之间的主要区别。假设我的同步方法是:

public virtual ActionResult Method()
{
   SomeLogic.LargeOperation();
   return View(...);
}

LargeOpertation做了很多。这是伪代码:

public void LargeOpertion() {
   DatabaseManipulations1();
   IndependentWork();
   CallingToWebService1();
   IndependentWork();    
   DatabaseManipulations2();
   IndependentWork();
   CallingToWebService2();
   IndependentWork(); 
}

LargeOperations中的每个方法本身都有几个方法,依此类推......问题是:我是否需要将它们全部异步并在几乎每个应用程序层中使用await?

public virtual Task<ActionResult> Method()
{
   await SomeLogic.LargeOperation();
   return View(...);
}

public async Task LargeOpertion() {
   await DatabaseManipulations1();
   IndependentWork();
   await CallingToWebService1();
   IndependentWork();    
   await DatabaseManipulations2();
   IndependentWork();
   await CallingToWebService2();
   IndependentWork(); 
}

或者我可以像这样在LargeOpertaion上使用任务:

public virtual Task<ActionResult> Method()
{
   await Task.Run(() => SomeLogic.LargeOperation());
   return View(...);
}

我们还假设IndependentWork()不是那么大。

1 个答案:

答案 0 :(得分:4)

  

由于一些优化问题,我决定将控制器的操作方法重写为异步操作方法。

在你开始之前,你应该意识到async会为你做什么以及它不会

异步操作运行速度不快。因此,对数据库的异步调用并不比对数据库的同步调用快。

await不会提前返回浏览器。它只是将当前线程释放回ASP.NET线程池。

因此,每个单独的请求仍然需要相同的总时间(实际上,只是稍微更长,但不是可检测的数量)。

async 帮助的是可伸缩性 - 即应用程序使用相同资源处理更多请求的能力。但是,它只会有助于 Web应用程序的可扩展性 - 它无法神奇地进入您的数据库并使 扩展。因此,如果您的可伸缩性瓶颈是您的数据库而不是ASP.NET(通常就是这种情况),那么async根本无法帮助您。

如果您的数据库后端是可扩展的(例如,NoSQL,Azure SQL或数据库集群),并且如果您的ASP.NET应用程序需要扩展,那么您可以从async中受益。

  

我是否需要将它们全部异步并在几乎每个应用程序层中使用await?

最好的方法是从“叶子”开始 - 最低级别的方法 - 并从那里开始工作。在这种情况下,从数据库交互开始,首先将它们转换为async

但是,您在任何时候都不应使用Task.RunTask.Factory.StartNew。相反,请使用真正的异步API,例如EF6中的async支持。