線程池
一直想把項目改寫成異步,但是ASP.NETMVC3下寫的過於繁瑣,.NET 4.5與ASP.NET MVC下代碼寫起來就比較簡單了, MS好像也一直喜歡這樣搞,每一個成熟的東西,都要演變好幾個版本,才能趨於規范。 ASP.NET MVC 中為什么需要使用異步呢,IIS有一個線程池來處理用戶的請求,當一個新的請求過來時,將調度池中的線程以處理該請求,然而,但並發量很高的情況下,池中的線程已經不能夠滿足這么多的請求時候,池中的每一個線程都處於忙的狀態則在處理請求時將阻塞處理請求的線程,並且該線程不能對另一個請求提供服務,如果請求隊列已滿,則 Web 服務器會拒絕請求並處於 HTTP 503繁忙狀態。如果是處理一些高延遲,例如網絡操作,這樣的線程大多數只是等待狀態大部分時間是不做任何事情的,這樣的線程就可以使用異步編程更好的充分利用。
異步處理
例如:如果某個請求生成一個需要兩秒鍾來完成的網絡調用,則該請求無論是同步執行還是異步執行都需要兩秒鍾。 但是,在異步調用的過程中,服務器在等待第一個請求完成的過程中不會阻塞對其他請求的響應。 因此,當有許多請求調用長時間運行的操作時,異步請求可以防止出現請求排隊的情況。在.NET 4.5中最大線程池為 5000 .NET 4.5中也增加了 await與async關鍵字來簡化異步編程。
同步還是異步(摘錄MSDN)
通常,在滿足以下條件時使用同步管線:
-
操作很簡單或運行時間很短。
-
簡單性比效率更重要。
-
此操作主要是 CPU 操作而不是包含大量的磁盤或網絡開銷的操作。 對 CPU 綁定操作使用異步操作方法未提供任何好處並且還導致更多的開銷。
通常,在滿足以下條件時使用異步管線:
-
操作是網絡綁定的或 I/O 綁定的而不是 CPU 綁定的。
-
測試顯示阻塞操作對於網站性能是一個瓶頸,並且通過對這些阻塞調用使用異步操作方法,IIS 可對更多的請求提供服務。
-
並行性比代碼的簡單性更重要。
-
您希望提供一種可讓用戶取消長時間運行的請求的機制。
ASP.NET MVC 中使用異步控制器
#region 1、異步請求 [AsyncTimeout(1000)] public async Task<ActionResult> Index() { var data = await GetPageTaskAsync("http://163.com"); return data; } public async Task<ActionResult> GetPageTaskAsync(string url) { try { using (var client = new HttpClient()) { await Task.Delay(3000); var fetchTextTask = client.GetStringAsync(url); return Json(new { fetchText = await fetchTextTask,error="NO" },JsonRequestBehavior.AllowGet); } } catch (WebException ex) { throw ex; } } #endregion
