1:XxxAsync/XxxCompleted
public class HomeController : AsyncController { // GET : /Home/Article (在繼承自AsyncController裡的Controller才能使用Article當Action名稱) // 非同步操作 public void ArticleAsync() { // 開始非同步的時候,先使用 AsyncManager.OutstandingOperations 取得一個 OperationCounter 對象, // 然後調用 Increment() 方法向系統發一個非同步操作開始的通知,OperationCounter 會 +1 // 結束的時候調用 Decrement(),OperationCounter 會 -1,在發法結束時,當OperationCounter 為 0 才會自動調用 ArticleCompleted() 方法 AsyncManager.OutstandingOperations.Increment(); string path = ControllerContext.HttpContext.Server.MapPath(string.Format(@"\Project_Readme.html")); StreamReader reader = new StreamReader(path); reader.ReadToEndAsync().ContinueWith(Task => { AsyncManager.Parameters["content"] = Task.Result; // 保存要給 ArticleCompleted() 方法的參數,必須與參數同名("content")才能自動匹配 AsyncManager.OutstandingOperations.Decrement(); // 自動調用 ArticleCompleted() 方法 reader.Close(); }); } // 非同步最終請求的響應,ArticleAsync 方法的回調 // content 參數來自 AsyncManager.Parameters["content"] public ActionResult ArticleCompleted(string content) { return Content(content); } }以 XxxAsync/XxxCompleted 方式定義非同步 Action 方法,表示說必需得為一個 Action 定義兩個方法(實際上可以通過一個方法完成 Action 非同步的定義,那就是讓 Action 方法返回一個代表非同步操作的 Task 對象)。
這方式只能出現在繼承自 AsyncController 的 Controller 中,但是 Task 方式沒有限制(保留 AsyncController 這個抽象類主要是為了實現對 ASP.NET MVC 3 的向後兼容)。
2:Task
public Task<ActionResult> Article()
{
string path = ControllerContext.HttpContext.Server.MapPath(string.Format(@"\Project_Readme.html"));
StreamReader reader = new StreamReader(path);
return reader.ReadToEndAsync().ContinueWith<ActionResult>(task =>
{
reader.Close();
return Content(task.Result);
});
}
由於 Action 返回一個 Task<ActionResult> 對象,所以可以利用 async/await 關鍵字 (C# 5.0) 直接將其標示為非同步
public async Task<ActionResult> Article()
{
string path = ControllerContext.HttpContext.Server.MapPath(string.Format(@"\Project_Readme.html"));
using (StreamReader reader = new StreamReader(path))
{
return Content(await reader.ReadToEndAsync());
}
}
沒有留言:
張貼留言