2013年3月18日 星期一

Asynchronous Controller

IIS 有一個自已的 TreadPool 用來處理用戶端提交的需求,TreadPool 中的 Thread 是有數量限制的,如果遇到以下狀況,就比較容易導至執行緒耗盡(thread starvation)的情況:

  • 大量的用戶端存取
  • 頻繁的 I/O bound 工作
  • 頻繁的外部網路存取工作

適時的採用非同步處理的作業模式可以減少系統被卡住的情形。 因為當非同步作業執行時,原先的執行緒會被釋放交還給 IIS ,讓它可以繼續處理其他用戶端的請求。 等到非同步作業執行結束,再將工作交還給 IIS 處理。

在 DotNet 4.5 中,只要使用非同步控制器動作,就可以輕鬆將原本同步作業調整成非同步作業模式。

建立非同步控制器

當建立控制器時,只要勾選「使用非同步控制器動作」,該控制器中自動建立的 action method 就會自動加入 async 和 await 等關鍵字以達到非同步作業的目的。

下列圖示中使用紅色記號,指出非同步作業的程式碼:

  • async 關鍵字是用來讓編譯器知道,這個 Index 方法執行結束後必須產生回呼,而且回傳 Task<ActionResult> 物件。
  • 當編譯器遇到 await 關鍵字時,它會暫停原先 Index 方法的運作,並建立新的 Task 去執行非同步作業的 method ,直到非同步作業方法執行完畢。
  • 叫用 ToList 的非同步方法。

上面範例有二個叫用非同步方法的地方: ToListAsnyc 和 FindAsync 。 要注意的是 linq 本身只會設定 sql 內容,真正要採用非同步的地方是將指令送到資料庫執行時,而在叫用 ToList 前,sql 指令是不會被執的,所以非同步方法會在 ToList 上,而不是在 departments = db.Departments 的描述上。

同樣的,若是處理 Add、Update、Delete 等狀況時, SaveChange 才是真正將指令送到資料庫執行的時刻,這時必須改叫用它的非同步方法。

沒有留言:

張貼留言