看stackoverflow大牛如何回答何時在ASP.NET中使用異步控制器?


今天無意中看到stackoverflow上一個很好的問答,個人覺得很有價值,所以翻譯過來和大家共享!希望大家能相互交流。

在ASP.NET MVC中何時使用異步控制器(Async Controllers)?##

在ASP.NET MVC中使用異步操作的時候,我有這么幾個關注點。異步操作何時提高我應用的性能,什么時候沒改善?###

  1. 在ASP.NET MVC中到處使用異步操作真的好嗎?
  2. 對於可等待的(awaitable)方法: 當查詢數據庫時(通過EF/NHibernate/其他的ORM)應該使用async/await關鍵字嗎?
  3. 在一個單獨的操作方法中,異步地查詢數據庫可以使用await關鍵字多少次?

當一個action必須執行多個獨立的長期運行的操作時,異步action方法是很有用的。
假設我有三個操作,分別耗時500, 600和700毫秒。采用同步調用的話,總共的響應時間將會稍微超過1800毫秒。然而,如果是異步調用(並發),總共響應時間將會稍微超過700毫秒,因為那是最長的任務/操作的持續時間。

異步控制器類一個經典的用法是用於長期運行的Web服務調用。

數據庫應該異步調用嗎?

IIS線程池經常可能處理比數據庫服務器更多的阻塞請求。如果數據庫遇到了瓶頸,那么異步的調用並不會加速數據庫的響應。由於沒有限流機制,使用異步調用有效地分發更多的任務給一個不知所措的數據庫服務器只會給數據庫轉移更多的負擔。如果你的數據庫遇到了瓶頸,異步調用不會是魔彈,只會是噩夢。

而且,異步並不意味着並發。異步執行釋放了一個沒有復雜度或性能損耗的外部資源阻塞的有價值的線程池線程。這意味着相同的IIS機器可以處理更多的並發請求,而不是它將運行的更快。

可以在MSDN上看一下這篇文章。作者花了很多精力在這篇博客上描述何時應該在ASP.NET中使用async而不是如何使用。

答標題問題:

首先,要理解async/await是釋放線程的根本。在GUI應用中,主要釋放GUI線程,因此用戶體驗更好。在服務器應用(包括ASP.NET MVC)中,主要釋放請求線程,因此服務器可以擴展。

特別地,它不會:

讓你的個人請求完成的更快。事實上,他們會完成的(只有一點點)更慢。當遇到一個await時,就會返回到調用者/瀏覽器。await只會向ASP.NET線程池“屈服”,而不是瀏覽器。

答問題1:

當你要進行I/O時,我可以說到處使用異步操作是好的。雖然它可能不一定是有益的(看下面)。

然而,對於CPU受限的方法使用異步操作是不好的。有時開發者認為通過在控制器中調用Task.Run可以獲得async的好處,這是一個可怕的觀點。因為那樣的代碼通過開啟其他線程來結束釋放該請求線程,因此根本沒有受益(事實上,他們消耗了額外線程切換的開銷)。

答問題2:###

你可以使用你可利用的任何可等待的方法。如果你的ORM不支持async,那么不要嘗試把它包裝在Task.Run或者任何和那個相似的東西里。

注意我說的是“你可以使用”。如果你在討論一個單數據庫的ASP.NET MVC,那么(基本上確定)你不會從async獲得任何伸縮性的好處。這是因為IIS可以比一個SQL Server(或者其他經典的RDBMS)的單一實例處理更多的並發請求。然而,如果你的后端是更現代的——SQL server集群, Azure SQL, NoSQL等等——你的后端可伸縮,並且伸縮性的瓶頸是IIS,那么你可以從async獲得伸縮性的好處。

答問題3:###

你愛用多少次就用多少次,只要你喜歡。然而,注意許多ORM都有“每次連接一次操作”的原則。特別的,EF每個DbContext只允許一個單獨的操作;無論該操作是同步的還是異步的,這都成立。

而且,再次記住你后端的伸縮性。如果你碰上了一個單一實例的SQL Server,且IIS已經可以使SQL Server處於滿負荷狀態,那么SQL Server雙倍或三倍的壓力對你一點好處都沒有。

原文翻譯自:這兒


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM