Web開發新手一直有個很困惑的問題?Web開發需要異步開發嗎?答案時肯定的,原因細細道來。
Web客戶端(瀏覽器)發送Http請求 -----> IIS服務器接受請求------>調用Asp.net,Asp.net為每個請求新建一個請求線程(通過一個線程池維護),因Asp.net請求線程所占資源比較大(一般請求線程是個確定值),那么在客戶端請求量超過“請求線程”數量,“請求”將放入等待隊列,等線程池中有空閑線程調用。所以因使用異步,在一些(IO操作、數據庫讀取、網絡請求)時不要阻塞“請求線程”。
Asp.net MVC中的異步
HttpHandler異步
MvcHandler為Asp.net中處理處理呈現,實現了IHttpHandler和IHttpAsyncHandler。Asp.net MVC總是按異步IHttpAsyncHandler執行。異步方法BeginProcessRequest和EndProcessRequest。
Controller執行的異步
Controller是通過ControllerFactory和ControllerName得到Controller實體。但是關於Controller的執行分為同步和異步,分別實現IController和IAsyncController。其中Controller同時實現了同步和異步,默認是按照異步執行的,可以重寫DisableAsyncSupport。這里正則執行的是BeginExecuteCore和EndExecuteCore分別存入委托。
注意 AsyncController與Controller同步異步沒關系,而是用於AMP的ActionInvoker的標記。
ActionInvoker異步
Controller中的Action最終是封裝到ActionInvoker執行的,關於Action的異步調用是最復雜的,是通過一套組件設置的。
首先關於IActionInvoker有同步有ControllerActionInvoker實現(如果通過ControllerActionInvoker則Action是為同步調用),IAsyncActionInvoker有AsyncControllerActionInvoker實現。在沒有注入時,默認為AsyncControllerActionInvoker(通過Controller.CreateActionInvoker()的方法得到)。
這里得到了ActionInvoker異步模式,但是執行Action需要封裝在ActionDecriptor下,而需要現貨的ContollerDescriptor。通過ActionInvoker.GetControllerDescriptor()方法獲得。
最終通過ActionDecriptor.Execute執行Action調用
接下來先大概接受下Asp.net MVC執行流程,在介紹下兩種異步執行Action的方式。

同步執行
- 這里從
MvcHandler處理呈現開始,通過IControllerFactory的到Controller - 執行
Controller,調用Execute,將Controller實體和ActionName傳入IActionInvoker ActionInvoker最終執行Action- 權限過濾
Filter - 得到
ControllerDescriptor/ActionDescriptor/ParameterDescriptor - 執行數據綁定和數據驗證
- 通過
actionDescriptor.Execute(controllerContext, parameters)執行Action返回ActionResult - 得到
ActionExecutedContext(其Result為Action返回值)。供View使用
- 權限過濾
AMP異步模式
異步實現要求
- 定義的
Controller繼承AsyncController(一個空類只為標記)抽象了 - 將一個
Action拆分為兩個方法XXXAsync/XXXCompleted注意XXXCompleted是回調方法,XXXAsync中函數中有異步操作需要AsyncManager
內部異步執行流程 Controller.CreateActionInvoker()得到AsyncControllerActionInvokerAsyncControllerActionInvoker.GetControllerDescriptor()得到ReflectedAsyncControllerDescriptorAsyncControllerActionInvoker.FindAction()得到ReflectedAsyncActionDescriptor
Task異步模式
返回類型為Task<>
內部異步執行流程
Controller.CreateActionInvoker()得到AsyncControllerActionInvokerAsyncControllerActionInvoker.GetControllerDescriptor()得到ReflectedAsyncControllerDescriptorAsyncControllerActionInvoker.FindAction()得到TaskAsyncActionDescriptor
