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()
得到AsyncControllerActionInvoker
AsyncControllerActionInvoker.GetControllerDescriptor()
得到ReflectedAsyncControllerDescriptor
AsyncControllerActionInvoker.FindAction()
得到ReflectedAsyncActionDescriptor
Task異步模式
返回類型為Task<>
內部異步執行流程
Controller.CreateActionInvoker()
得到AsyncControllerActionInvoker
AsyncControllerActionInvoker.GetControllerDescriptor()
得到ReflectedAsyncControllerDescriptor
AsyncControllerActionInvoker.FindAction()
得到TaskAsyncActionDescriptor