異步Action之AsyncController

1.爲何須要異步Action

  池的模式一直是咱們處理對象頻繁建立、銷燬時採起的一種策略。就像一個大型圖書館,當咱們須要某種圖書的時候只須要到裏面尋找就能夠了,使用完畢以後放回;而不是每次想要獲取的時候通知印刷廠爲咱們印刷一本。ASP.NET對HTTP的請求處理也是採用了線程池的方式,每一個web應用內部都維護着一個線程池,當請求到達以後ASP.NET會從線程池中取出一個空閒的線程來專門處理此次請求,請求結束以後線程也不是被直接銷燬而是放回到線程池供其餘請求使用。須要注意的是線程池有一個最大容量若是請求數量超過這個容量ASP.NET會採起隊列排隊的方式對請求進行排隊,這個時候咱們就會感受到網頁的響應時間邊長,就像圖書館裏面只有10本書如今來了20我的想要借書那麼咱們就讓多餘的人進行排隊。web

  線程池的設計能夠給咱們帶來如下優勢服務器

  · 線程重用:線程的建立和銷燬一樣須要佔用服務器資源,採用線程池設計避免了頻繁的建立和銷燬進而提升服務器的吞吐能力(能夠有更多的資源用於其餘方面)多線程

  · 最大數量限制:最大數量限制避免了建立過多線程致使的服務器崩潰現象  mvc

  若是請求的處理過程很短,線程池內的線程在使用後會被很快的從新放回線程池,這固然是最理想的狀態。但若是請求處理過程很長(好比IO處理)那麼就會致使線程不能被快速使用完畢後放回至線程池,影響服務器吞吐能力。異步即爲了解決這一問題,咱們能夠在線程池裏的線程在使用時若是遇到耗時操做(主要針對IO)爲其建立一個後臺線程專門處理耗時操做,從而讓線程池中的線程能夠儘快返還到線程池中提升服務器吞吐能力。異步

2.異步Action定義

  在mvc3的版本中提供了定義異步Action的一種方式,即建立XxxAsync()方法和XxxCompleted()兩個方法,XxxCompleted()方法是XxxAsync()方法執行完畢以後的回調方法。ASP.NET並不會以異步的方式執行XxxAsync()方法,而是咱們在XxxAsync()方法內自行實現異步。MVC4之後的版本咱們可使用Task完成異步操做。ide

 1     public class HomeController : AsyncController
 2     {
 3 
 4         public void IndexAsync()
 5         {
 6             //異步執行開始標誌
 7             AsyncManager.OutstandingOperations.Increment();
 8             Task.Factory.StartNew(() =>
 9             {
10                 string path = ControllerContext.HttpContext.Server.MapPath("\\Texts\\圍城.txt");
11                 using (StreamReader sr = new StreamReader(path))
12                 {
13                     //回調時傳遞的參數
14                     AsyncManager.Parameters["Content"] = sr.ReadToEnd();
15                 }
16                 AsyncManager.Parameters["count"] = 1;
17                 AsyncManager.Parameters["person"] = new Person { Name = "張三" };
18                 //異步執行結束標誌 ①
19                 AsyncManager.OutstandingOperations.Decrement();
20             });
21             //
22 
23         }
24 
25         public ActionResult IndexCompleted(string content, int count,Person person)
26         {
27             return Content(content);
28         }
29 
30     }
31 
32     public class Person
33     {
34         public string Name { set; get; }
35     }
AsyncController

  跟蹤執行過程spa

  此種方式操做起來相對比較麻煩。並且通常須要藉助於AcynManager對象完成異步操做。線程

3.AsyncManager

   首先咱們把代碼中標註①的代碼放到//②的位置,再跟蹤代碼會發現IndexCompleted(string content, int count,Person person)方法中的參數有時會被賦值有時爲null,設計

這又是爲何呢?code

  AsyncManager.OutstandingOperations.Decrement();標誌後臺線程執行完畢,此時能夠開始執行IndexCompleted方法,若是把它放到②位置處則只是通知IndexAsync方法執行完畢,至於Task.Factory.StartNew中的後臺任務不必定執行完畢,因此出現上述狀況,所以使用此種方式設計一部Action時咱們須要注意AsyncManager.OutstandingOperations.Decrement();的位置。

相關文章
相關標籤/搜索