ASP.NET底層原理

上圖基本上演示了IIS 6整個處理過程。在User Mode下,http.sys接收到一個基於aspx的http request,而後它會根據IIS中的Metabase查看該基於該Request的Application屬於哪一個Application Pool,若是該Application Pool不存在,則建立之。不然直接將request發到對應Application Pool的Queue中。我上面已經說了,每一個Application Pool對應着一個Worker Process:w3wp.exe,毫無疑問他是運行在User Mode下的。在IIS Metabase中維護着Application Pool和worker process的Mapping。WAS(Web Administrative service)根據這樣一個mapping,將存在於某個Application Pool Queue的request 傳遞到對應的worker process(若是沒有,就建立這樣一個進程)。在worker process初始化的時候,加載ASP.NET ISAPI,ASP.NET ISAPI進而加載CLR。從而爲ASP.NET Application建立一個託管的運行環境,在CLR初始化的使用會加載兩個重要的dll:AppManagerAppDomainFactory和ISAPIRuntime。經過AppManagerAppDomainFactory的Create方法爲Application建立一個Application Domain;經過ISAPIRuntime的ProcessRequest處理Request,進而將流程拖入到ASP.NET Http Runtime Pipeline的範疇,ASP.NET Http Runtime Pipeline對Http Request的處理是一個相對複雜的過程,相關的介紹會放在本篇文章的下一部份。在這裏咱們能夠把它當作是一個黑盒,它接管Request,最終生成Html。html

ISAPIRuntime會首先建立一個ISAPIWorkRequest對象,對請求報文進行了簡單的封裝,並將該ISAPIWorkRequest對象傳遞給HttpRuntime。api

HttpRuntime會根據ISAPIWorkRequest建立用於封裝Http請求上下文的對象HttpConetxt。服務器

  HttpContext主要包括HttpRequest(當前請求)和HttpResponse(服務器響應)app

[SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
public int ProcessRequest(IntPtr ecb, int iWRType)
{
    IntPtr zero = IntPtr.Zero;
    if (iWRType == 2)
    {
        zero = ecb;
        ecb = UnsafeNativeMethods.GetEcb(zero);
    }
    //建立了ISAPIWorkRquest空對象
    ISAPIWorkerRequest wr = null;
    try
    {
        bool useOOP = iWRType == 1;
    //經過ecb句柄建立了ISAPIWorkRequest對象
        wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);
        wr.Initialize();
        string appPathTranslated = wr.GetAppPathTranslated();
        string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal;
        if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal))
        {
        //IsapiRuntime把WR交給了HttpRuntime
            HttpRuntime.ProcessRequestNoDemand(wr);
            return 0;
        }
        HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated }));
        return 1;
    }
    catch (Exception exception)
    {
        try
        {
            WebBaseEvent.RaiseRuntimeError(exception, this);
        }
        catch
        {
        }
        if ((wr == null) || !(wr.Ecb == IntPtr.Zero))
        {
            throw;
        }
        if (zero != IntPtr.Zero)
        {
            UnsafeNativeMethods.SetDoneWithSessionCalled(zero);
        }
        if (exception is ThreadAbortException)
        {
            Thread.ResetAbort();
        }
        return 0;
    }
}

 

ISAPIRuntime
View Code

 HttpRuntime經過HttpApplicationFactory獲取一個新的或現有的HttpApplication對象。async

private void ProcessRequestInternal(HttpWorkerRequest wr)
{
    Interlocked.Increment(ref this._activeRequestCount);
    if (this._disposingHttpRuntime)
    {
        try
        {
            wr.SendStatus(0x1f7, "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);
        }
    }
    else
    {
        HttpContext context;
        try
        {
        //經過wr建立了上下文對象
            context = new HttpContext(wr, false);
        }
        catch
        {
            try
            {
                wr.SendStatus(400, "Bad Request");
                wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
                byte[] data = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");
                wr.SendResponseFromMemory(data, data.Length);
                wr.FlushResponse(true);
                wr.EndOfRequest();
                return;
            }
            finally
            {
                Interlocked.Decrement(ref this._activeRequestCount);
            }
        }
        wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context);
        HostingEnvironment.IncrementBusyCount();
        try
        {
            try
            {
                this.EnsureFirstRequestInit(context);
            }
            catch
            {
                if (!context.Request.IsDebuggingRequest)
                {
                    throw;
                }
            }
            context.Response.InitResponseWriter();
        
        //經過HttpApplicationFactory獲取HttpApplication實例
            IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);
            if (applicationInstance == null)
            {
                throw new HttpException(SR.GetString("Unable_create_app_object"));
            }
            if (EtwTrace.IsTraceEnabled(5, 1))
            {
                EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, applicationInstance.GetType().FullName, "Start");
            }
            if (applicationInstance is IHttpAsyncHandler)
            {
                IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance;
                context.AsyncAppHandler = handler2;

            //執行HttpApplication的BeginProcessRequest方法
                handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context);
            }
            else
            {
                applicationInstance.ProcessRequest(context);
                this.FinishRequest(context.WorkerRequest, context, null);
            }
        }
        catch (Exception exception)
        {
            context.Response.InitResponseWriter();
            this.FinishRequest(wr, context, exception);
        }
    }
}

HttpRuntime
View Code
相關文章
相關標籤/搜索