Action方法的執行具有兩種基本的形式,即同步執行和異步執行,而在ASP.NETMVC的整個體系中涉及到很多同步/異步的執行方式,雖然在前面相應的文章中已經對此作了相應的介紹,為了讓讀者對此有一個整體的了解,我們來做一個總結性的論述。
一、MvcHandler的同步與異步
對於ASP.NET MVC應用來說,MvcHandler是最終用於處理請求的HttpHandler,它是通過UrlRoutingModule這個實現了URL路由的HttpModule被動態映射到相應的請求的。MvcHandler借助於ControllerFactory激活並執行目標Controller,並在執行結束後負責對激活的Controller進行釋放,相關的內容請參與本書的第3章“Controller的激活”。如下面的代碼片斷所示,MvcHandler同時實現了IHttpHandler和IHttpAsyncHandler接口,所以它總是調用BeginProcessRequest/EndProcessRequest方法以異步的方式來處理請求。
1: public class MvcHandler : IHttpAsyncHandler, IHttpHandler, ...
2: {
3: //其他成員
4: IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);
5: void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result);
6: void IHttpHandler.ProcessRequest(HttpContext httpContext);
7: }
二、Controller的同步與異步
Controller也具有同步與異步兩個版本,它們分別實現了具有如下定義的兩個接口IController和IAsyncController。當激活的Controller對象在MvcHandler的BeginProcessRequest方法中是按照這樣的方式執行的:如果Controller的類型實現了IAsyncController接口,則調用BeginExecute/EndExecute方法以異步的方式執行Controller;否則Controller的執行通過調用Execute方法以同步方式執行。
1: public interface IController
2: {
3: void Execute(RequestContext requestContext);
4: }
5: public interface IAsyncController : IController
6: {
7: IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state);
8: void EndExecute(IAsyncResult asyncResult);
9: }
默認情況下通過Visual Studio的向導創建的Controller類型是抽象類型Controller的子類。如下面的代碼片斷所示,Controller同時實現了IController和IAsyncController這兩個接口,所以當MvcHandler進行請求處理時總是以異步的方式來執行Controller。
1: public abstract class Controller : ControllerBase, IController, IAsyncController, ...
2: {
3: //其他成員
4: protected virtual bool DisableAsyncSupport
5: {
6: get{return false;}
7: }
8: }
但是Controller類型具有一個受保護的只讀屬性DisableAsyncSupport用於表示是否禁用對異步執行的支持。在默認情況下,該屬性值為False,所以默認情況下是支持Controller的異步執行的。如果我們通過重寫該屬性將值設置為True,那麼Controller將只能以同步的方式執行。具體的實現邏輯體現在如下的代碼片斷中:BeginExecute方法在DisableAsyncSupport屬性為True的情況下通過調用Execute方法(該方法會調用一個受保護的虛方法ExecuteCore最終對Controller進行同步執行);否則通過調用BeginExecuteCore/EndExecuteCore以異步方式執行Controller。
1: public abstract class Controller: ...
2: {
3: //其他成員
4: protected virtual IAsyncResult BeginExecute(RequestContext requestContext,
5: AsyncCallback callback, object state)
6: {
7: if (this.DisableAsyncSupport)
8: {
9: //通過調用Execute方法同步執行Controller
10: }
11: else
12: {
13: //通過調用BeginExecuteCore/EndExecuteCore方法異步執行Controller
14: }
15: }
16: protected override void ExecuteCore();
17: protected virtual IAsyncResult BeginExecuteCore(AsyncCallback callback, object state);
18: protected virtual void EndExecuteCore(IAsyncResult asyncResult);
19: }