Asp.net MVC 3 異步操作


     在 Asp.net MVC 應用程序中,有時間需要執行一些異步操作。那么 Asp.net MVC 下的異步請求是怎么一個過程呢?  異步被調用時,發生以下過程:

1. Web服務器從線程池得到一個線程(工作線程),接着安排它來處理進來的請求,該工作線程啟動一個異步操作。

2. 工作線程被線程池收回,為另一個Web請求服務。

3. 當異步操作完成后,它會通知ASP.NET。

4. Web服務器從線程池獲取一個工作線程(這可能是一個不同的開始異步操作的線程)來處理剩余的請求,包括呈現與響應請求。


看下面的模式圖:

IC371798Async


接着,我們來看Controller的代碼:

   1:      public class HomeController : AsyncController
   2:      {
   3:          public void IndexAsync()
   4:          {
   5:              AsyncManager.OutstandingOperations.Increment(2);
   6:   
   7:              Task.Factory.StartNew(() =>
   8:                                        {
   9:                                            // Perform some expensive operation
  10:                                            string uri = "http://www.cnblogs.com";
  11:   
  12:                                            WebClient client = new WebClient();
  13:                                            string reply = client.DownloadString(uri);
  14:   
  15:                                            AsyncManager.Parameters["data"] = reply;
  16:                                            AsyncManager.OutstandingOperations.Decrement();
  17:                                        });
  18:              Task.Factory.StartNew(() =>
  19:                                        {
  20:                                            // Perform another expensive operation
  21:                                            string uri = "http://www.cnblogs.com/wintersun/";
  22:   
  23:                                            WebClient client = new WebClient();
  24:                                            string reply = client.DownloadString(uri);
  25:   
  26:                                            AsyncManager.Parameters["moredata"] = reply;
  27:                                            AsyncManager.OutstandingOperations.Decrement();
  28:                                        });
  29:          }
  30:   
  31:          public ActionResult IndexCompleted(string data, string moredata)
  32:          {
  33:              Operations translations = new Operations { FirstOperation = data, SecondOperation = moredata };
  34:   
  35:              return View(translations);
  36:          }
  37:   
  38:      }


我們看到上面的代碼讓Controller繼承自AsyncController,那個叫IndexAsync的action對應是Index的View。中間的代碼使用Task Parallel library(TPL)來模擬下載網頁內容,最后在完成后又通過AsyncManager.Parameters字典傳值給IndexCompleted的Action, 有注意Key的名稱moredata與IndexCompleted Action的參數名moredata相同。AsyncManager下的Parameters字典用於轉遞一組參數值到最后異步調用的方法。 AsyncManager下有一個管理異步操作的計數器,應當務必確保執行異步操作后,執行Decrement方法,甚至異步操作失敗,當所有線程完成時這個計數器的值必須為0。 當異步調用我們讓View返回:


   1:  <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<AsyncProject.Models.Operations>" %>
   2:  <!DOCTYPE html>
   3:  <html>
   4:  <head runat="server">
   5:      <title>Translate Completed</title>
   6:  </head>
   7:  <body>
   8:      <div>
   9:          The controller has completed.
  10:      </div>
  11:  </body>
  12:  </html>


使用到一個簡單Model:

    public class Operations
    {
        public string FirstOperation { get; set; }
        public string SecondOperation { get; set; }
    }


好了,那么什么時候用異步,什么用同步呢?

當這些條件滿足的情況下,可以考慮使用異步:

1. 密集​​地操作的網絡或I/O,而不是CPU密集運算的。
2. 測試結果表明阻塞操作是網站的性能瓶頸,為了讓IIS服務器可以處理更多的請求,在處理這些阻塞調用時使用異步Action方法。
3. 並行化比簡單代碼更重要。
4. 需要提供一種機制,允許用戶取消一個長期運行任務的請求。

實際開發,你需要測試是否異步操作可以提高性能。同時,在某些情況下可能話,增加IIS每個CPU配置最大並發請求處理和最大並發線程。

關於Asp.net 服務器線程配置看這篇文章:ASP.NET Thread Usage on IIS 7.5, IIS 7.0, and IIS 6.0
關於是否需要數據庫異步調用看這里: Should my database calls be Asynchronous

我們介紹到這兒,有興趣可以自己嘗試一下,后面有時間將介紹Asp.net MVC 4 與 .net framework 4.5 的異步操作。

 


作者:Petter Liu
出處:http://www.cnblogs.com/wintersun/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
該文章也同時發布在我的獨立博客中-Petter Liu Blog


免責聲明!

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



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