上一節說在urlroutingmodule中mvchandler 映射到httpcontext上,那mvchandler又是怎麼執行的呢?html
(1)、httpruntimeapi
從isapiruntime pr方法到httpruntimemvc
ProcessRequestNoDemand(wr)方法app
// System.Web.HttpRuntime internal static void ProcessRequestNoDemand(HttpWorkerRequest wr) {
//獲取請求隊列 RequestQueue requestQueue = HttpRuntime._theRuntime._requestQueue; wr.UpdateInitialCounters(); if (requestQueue != null) { wr = requestQueue.GetRequestToExecute(wr); } if (wr != null) { HttpRuntime.CalculateWaitTimeAndUpdatePerfCounter(wr); wr.ResetStartTime(); HttpRuntime.ProcessRequestNow(wr); } }
ProcessRequestNow(wr)方法async
// System.Web.HttpRuntime internal static void ProcessRequestNow(HttpWorkerRequest wr) { HttpRuntime._theRuntime.ProcessRequestInternal(wr); }
ProcessRequestInternal(wr)方法ui
// System.Web.HttpRuntime private void ProcessRequestInternal(HttpWorkerRequest wr) {
//活動請求數量增長 Interlocked.Increment(ref this._activeRequestCount);
//判斷請求數異常 if (this._disposingHttpRuntime) { try { wr.SendStatus(503, "Server Too Busy"); wr.SendKnownResponseHeader(12, "text/html; charset=utf-8"); byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Server Too Busy</body></html>"); wr.SendResponseFromMemory(bytes, bytes.Length); wr.FlushResponse(true); wr.EndOfRequest(); } finally { Interlocked.Decrement(ref this._activeRequestCount); } return; } HttpContext httpContext; try {
//HttpWorkerRequest轉HttpContext httpContext = new HttpContext(wr, false); } catch { try { wr.SendStatus(400, "Bad Request"); wr.SendKnownResponseHeader(12, "text/html; charset=utf-8"); byte[] bytes2 = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>"); wr.SendResponseFromMemory(bytes2, bytes2.Length); wr.FlushResponse(true); wr.EndOfRequest(); return; } finally { Interlocked.Decrement(ref this._activeRequestCount); } } wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, httpContext); HostingEnvironment.IncrementBusyCount(); try { try { this.EnsureFirstRequestInit(httpContext); } catch { if (!httpContext.Request.IsDebuggingRequest) { throw; } } httpContext.Response.InitResponseWriter();
//獲取application實例 IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(httpContext); if (applicationInstance == null) { throw new HttpException(SR.GetString("Unable_create_app_object")); } if (EtwTrace.IsTraceEnabled(5, 1)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, httpContext.WorkerRequest, applicationInstance.GetType().FullName, "Start"); }
//判斷application實例是否有繼承IHttpAsyncHandler if (applicationInstance is IHttpAsyncHandler) { IHttpAsyncHandler httpAsyncHandler = (IHttpAsyncHandler)applicationInstance; httpContext.AsyncAppHandler = httpAsyncHandler;
//執行application的BeginProcessRequest httpAsyncHandler.BeginProcessRequest(httpContext, this._handlerCompletionCallback, httpContext); } else { applicationInstance.ProcessRequest(httpContext); this.FinishRequest(httpContext.WorkerRequest, httpContext, null); } } catch (Exception e) { httpContext.Response.InitResponseWriter(); this.FinishRequest(wr, httpContext, e); } }
BeginProcessRequest方法this
IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { this._context = context; this._context.ApplicationInstance = this;
this._stepManager.InitRequest(); this._context.Root(); HttpAsyncResult httpAsyncResult = new HttpAsyncResult(cb, extraData); this.AsyncResult = httpAsyncResult; if (this._context.TraceIsEnabled) { HttpRuntime.Profile.StartRequest(this._context); }
//執行步驟 this.ResumeSteps(null); return httpAsyncResult; }
ResumeSteps方法url
private void ResumeSteps(Exception error) { this._stepManager.ResumeSteps(error); }
this._stepManager 抽象類spa
internal abstract class StepManager { protected HttpApplication _application; protected bool _requestCompleted; internal bool IsCompleted { get { return this._requestCompleted; } } internal StepManager(HttpApplication application) { this._application = application; } internal abstract void BuildSteps(WaitCallback stepCallback); internal void CompleteRequest() { this._requestCompleted = true; if (HttpRuntime.UseIntegratedPipeline) { HttpContext context = this._application.Context; if (context != null && context.NotificationContext != null) { context.NotificationContext.RequestCompleted = true; } } } internal abstract void InitRequest(); internal abstract void ResumeSteps(Exception error); }