2013-10-24 145 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可以通過對這些阻止調用使用異步方法來處理更多請求。