2013-10-24 102 views
17

我一直在寻找在ASP.NET MVC 5个模板和我有注意到许多行动,并被标记为异步:异步操作方法

public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { } 

当我应该这样做上的MVC行动?它包含对数据库的访问权限?

如果我在动作中调用存储库,我还应该使用Task使其成为异步?

回答

11

你问题的核心是:什么时候应该让我的MVC动作异步?有关此问题的详细讨论,请参阅http://blogs.msdn.com/b/rickandy/archive/2009/11/14/should-my-database-calls-be-asynchronous.aspx。他只谈论数据库,但他的观点继续存在。

本质上,几乎从不以异步方式调用数据库。

对于使用异步操作,以减少在Web服务器上阻塞的线程数的数据库应用程序是几乎总是时间完全是浪费。

不要被人们告诫,如果可能的话总是使用异步IO。异步是现在所有的愤怒。洛特的非理性建议正在传播。

+2

应该改变,引用的文章有一个从2012年11月28日更新说明...“等待,异步和任务对象的组合使您更容易编写.NET 4.5中的异步代码现在EF 6正在支持Async Query和Save,你应该利用异步编程“ –

+1

@PaulHatcher我完全不同意这个结论。看到我关于这个主题的其他部分:http://stackoverflow.com/a/25087273/122718和http://stackoverflow.com/a/12796711/122718。如果整个社区跳上一项新的酷技术,没有人真正说过为什么那么你应该开始提问。 – usr

9

实体框架6(默认使用MVC 5)现在支持异步数据库调用,所以操作方法签名已更新以反映正在使用的异步。简单的答案是,只要您有可能涉及等待的任务,请使用异步。希望你的数据库查询不需要花费很长时间才能真正从async中获益,但是如果你的数据库崩溃或者特别困难,它至少可以帮助在这个过程中不会死锁IIS。

+0

此建议需要说明理由。 – usr

+0

@usr:你在寻找什么样的理由?理由已经存在。如果数据库服务器由于某种原因需要特别长的时间响应请求,那么您会给IIS一些喘息空间来处理额外的请求。异步的本质意味着,当线程处于等待状态时,它可以返回到池中执行其他工作,而不是坐在那里锁定,等待任务完成。 –

+1

如果您希望数据库平均在10ms内响应,并且需要10s,则可以返回所需的所有线程。该应用程序已关闭。 ASP.NET中的线程并不稀缺。默认情况下有数百个,并且没有公共数据库可以从这么多的并行请求中受益。异步数据库调用的情况很弱。 – usr

5

这里有一篇文章列出了一些用例,当使用任务可能会有好处,有些使用 时可能会有相反的效果。 答案并非每次都这么简单,这就是为什么关于测试的最后一点。从http://www.asp.net/mvc/overview/performance/using-asynchronous-methods-in-aspnet-mvc-4

一般而言

报价,使用同步方法在下列条件:

  • 的操作是简单的或短期运行。
  • 简单性比效率更重要。
  • 这些操作主要是CPU操作,而不是涉及大量磁盘或网络开销的操作。在CPU绑定的操作上使用异步的 操作方法没有任何好处,并且 会导致更多开销。

一般情况下,使用异步方法如下条件:

  • 你打电话,可通过异步方法来消费的服务,而你正在使用.NET 4.5或更高版本。
  • 这些操作是网络绑定或I/O绑定而不是CPU绑定的。并行性比代码的简单性更重要。
  • 您想要提供一种机制,让用户取消长时间运行的请求。
  • 当切换线程的好处权衡了上下文切换的成本。通常,如果 同步方法在ASP.NET请求线程上等待,而 没有工作,则应该使方法异步。通过使调用异步,ASP.NET请求线程 不会暂停,在等待Web服务 请求完成时不做任何工作。
  • 测试显示阻止操作是站点性能的瓶颈,IIS可以通过对这些阻止调用使用异步方法来处理更多请求。