MVC源码解析 – HttpRuntime解析。MVC源码解析 – HttpRuntime解析。

先行押同样张图, 从即张图里, 能看到请是什么样由CLR进入HttpRuntime的.

先押一样摆图, 从当时张图里, 能看到要是怎从CLR进入HttpRuntime的.

爱博体育app手机版 1

爱博体育app手机版 2

一、AppManagerAppDomainFactory 

一、AppManagerAppDomainFactory 

望这张图是由 AppManagerAppDomainFactory 开始的,
按照汤姆大叔博文中所说, 是在CLR初始化加载的当儿, 来加载是仿佛的.
那么来拘禁一下夫类似吧.

来看就张图是自 AppManagerAppDomainFactory 开始之,
按照汤姆大叔博文被所说, 是在CLR初始化加载的时节, 来加载是看似的.
那么来拘禁一下是近乎吧.

使用Reflector反编译搜索AppManagerAppDomainFactory 类, 可以看出(由于这个看似并无多,
那么自己事先贴一个完的出吧):

行使Reflector反编译搜索AppManagerAppDomainFactory 类, 可以见见(由于这个近乎并无多,
那么我先行贴一个总体的下吧):

[SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
public sealed class AppManagerAppDomainFactory : IAppManagerAppDomainFactory
{
    // Fields
    private ApplicationManager _appManager = ApplicationManager.GetApplicationManager();

    // Methods
    public AppManagerAppDomainFactory()
    {
        this._appManager.Open();
    }

    internal static string ConstructSimpleAppName(string virtPath)
    {
        if (virtPath.Length > 1)
        {
            return virtPath.Substring(1).ToLower(CultureInfo.InvariantCulture).Replace('/', '_');
        }
        if (!BuildManagerHost.InClientBuildManager && HostingEnvironment.IsDevelopmentEnvironment)
        {
            return "vs";
        }
        return "root";
    }

    [return: MarshalAs(UnmanagedType.Interface)]
    public object Create(string appId, string appPath)
    {
        object obj2;
        try
        {
            if (appPath[0] == '.')
            {
                FileInfo info = new FileInfo(appPath);
                appPath = info.FullName;
            }
            if (!StringUtil.StringEndsWith(appPath, '\\'))
            {
                appPath = appPath + @"\";
            }
            ISAPIApplicationHost appHost = new ISAPIApplicationHost(appId, appPath, false);
            ISAPIRuntime o = (ISAPIRuntime) this._appManager.CreateObjectInternal(appId, typeof(ISAPIRuntime), appHost, false, null);
            o.StartProcessing();
            obj2 = new ObjectHandle(o);
        }
        catch (Exception)
        {
            throw;
        }
        return obj2;
    }

    public void Stop()
    {
        this._appManager.Close();
    }
}
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
public sealed class AppManagerAppDomainFactory : IAppManagerAppDomainFactory
{
    // Fields
    private ApplicationManager _appManager = ApplicationManager.GetApplicationManager();

    // Methods
    public AppManagerAppDomainFactory()
    {
        this._appManager.Open();
    }

    internal static string ConstructSimpleAppName(string virtPath)
    {
        if (virtPath.Length > 1)
        {
            return virtPath.Substring(1).ToLower(CultureInfo.InvariantCulture).Replace('/', '_');
        }
        if (!BuildManagerHost.InClientBuildManager && HostingEnvironment.IsDevelopmentEnvironment)
        {
            return "vs";
        }
        return "root";
    }

    [return: MarshalAs(UnmanagedType.Interface)]
    public object Create(string appId, string appPath)
    {
        object obj2;
        try
        {
            if (appPath[0] == '.')
            {
                FileInfo info = new FileInfo(appPath);
                appPath = info.FullName;
            }
            if (!StringUtil.StringEndsWith(appPath, '\\'))
            {
                appPath = appPath + @"\";
            }
            ISAPIApplicationHost appHost = new ISAPIApplicationHost(appId, appPath, false);
            ISAPIRuntime o = (ISAPIRuntime) this._appManager.CreateObjectInternal(appId, typeof(ISAPIRuntime), appHost, false, null);
            o.StartProcessing();
            obj2 = new ObjectHandle(o);
        }
        catch (Exception)
        {
            throw;
        }
        return obj2;
    }

    public void Stop()
    {
        this._appManager.Close();
    }
}

关于此详细的分解, 推荐去
MVC之前的那些事儿 去见,
这里连无是自家思念发挥的机要, 就不介绍了. 

关于此详细的分解, 推荐去
MVC之前的那些事儿 去见,
这里并无是我思念发挥的重要性, 就无介绍了. 

比方知道, 按照大叔的布道, 这里, 在CreateObjectInternal方法吃, 创建了AppDomain,
创建了HostingEnvironment等有列操作.

要了解, 按照大叔的传道, 这里, 在CreateObjectInternal方法被, 创建了AppDomain,
创建了HostingEnvironment等一些列操作.

继往开来有的以HttpRuntime, HttpContext等,
都是依托于这AppDomain. 

后续有的比如HttpRuntime, HttpContext等,
都是寄于之AppDomain. 

 

 

二、主题

二、主题

通过各种我非理解之里边处理, 非托管代码开始正儿八经调用 ISAPIRuntime 的
ProcessRequest(后面简称也PR方法)了.

由此各种我莫明白之中处理, 非托管代码开始正式调用 ISAPIRuntime 的
ProcessRequest(后面简称也PR方法)了.

(ISPAIRuntime继承了IISPAIRuntime接口,该接口可以跟COM进行互动,并且暴露了ProcessRequest接口方法)

(ISPAIRuntime继承了IISPAIRuntime接口,该接口可以与COM进行互动,并且暴露了ProcessRequest接口方法)

毫不问我何以会调用PR方法, 因为我哉无理解, 但是真正是者方法. 

永不问我干什么会调用PR方法, 因为我吧无明白, 但是实在是这方法. 

public sealed class ISAPIRuntime : MarshalByRefObject, IISAPIRuntime, IISAPIRuntime2, IRegisteredObject
{
    // Fields
    private static int _isThisAppDomainRemovedFromUnmanagedTable;
    private const int WORKER_REQUEST_TYPE_IN_PROC = 0;
    private const int WORKER_REQUEST_TYPE_IN_PROC_VERSION_2 = 2;
    private const int WORKER_REQUEST_TYPE_OOP = 1;

    // Methods
    [SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
    public ISAPIRuntime();
    [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
    public void DoGCCollect();
    public override object InitializeLifetimeService();
    [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
    public int ProcessRequest(IntPtr ecb, int iWRType);
    internal static void RemoveThisAppDomainFromUnmanagedTable();
    [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
    public void StartProcessing();
    [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
    public void StopProcessing();
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    void IISAPIRuntime2.DoGCCollect();
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    int IISAPIRuntime2.ProcessRequest(IntPtr ecb, int iWRType);
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    void IISAPIRuntime2.StartProcessing();
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    void IISAPIRuntime2.StopProcessing();
    void IRegisteredObject.Stop(bool immediate);
}
public sealed class ISAPIRuntime : MarshalByRefObject, IISAPIRuntime, IISAPIRuntime2, IRegisteredObject
{
    // Fields
    private static int _isThisAppDomainRemovedFromUnmanagedTable;
    private const int WORKER_REQUEST_TYPE_IN_PROC = 0;
    private const int WORKER_REQUEST_TYPE_IN_PROC_VERSION_2 = 2;
    private const int WORKER_REQUEST_TYPE_OOP = 1;

    // Methods
    [SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
    public ISAPIRuntime();
    [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
    public void DoGCCollect();
    public override object InitializeLifetimeService();
    [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
    public int ProcessRequest(IntPtr ecb, int iWRType);
    internal static void RemoveThisAppDomainFromUnmanagedTable();
    [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
    public void StartProcessing();
    [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
    public void StopProcessing();
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    void IISAPIRuntime2.DoGCCollect();
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    int IISAPIRuntime2.ProcessRequest(IntPtr ecb, int iWRType);
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    void IISAPIRuntime2.StartProcessing();
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    void IISAPIRuntime2.StopProcessing();
    void IRegisteredObject.Stop(bool immediate);
}

此处来只办法, 看名字即觉着好习, 好吧, 点进去看一下:

这边发出只道, 看名字就是看好习, 好吧, 点进去看一下:

爱博体育app手机版 3

爱博体育app手机版 4

GC 一个深受垃圾回收的东东, 好熟悉的名字. OK, 这不是主要, 接下来继续.

GC 一个让垃圾回收的东东, 好熟悉的名字. OK, 这不是重大, 接下来继续.

[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);
    }
    ISAPIWorkerRequest wr = null;
    try
    {
        bool useOOP = iWRType == 1;
        wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);
        wr.Initialize();
        string appPathTranslated = wr.GetAppPathTranslated();
        string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal;
        if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal))
        {
            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;
    }
}
[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);
    }
    ISAPIWorkerRequest wr = null;
    try
    {
        bool useOOP = iWRType == 1;
        wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);
        wr.Initialize();
        string appPathTranslated = wr.GetAppPathTranslated();
        string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal;
        if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal))
        {
            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;
    }
}

先是个注意到之就是拖欠措施的IntPtr类型的参数ecb,ecb是甚?ecb是一个非托管的指针,全称是Execution
Control Block,在总体Http Request
Processing过程遭到于在大关键之打算,我们现在来简单介绍一个ECB。

先是个注意到的即是该办法的IntPtr类型的参数ecb,ecb是啥?ecb是一个非托管的指针,全称是Execution
Control Block,在所有Http Request
Processing过程中自在好重要的企图,我们现在来简单介绍一个ECB。

 

 

非托管环境ISAPI对ISAPIRuntime的调用,需要传递一些亟须的多寡,比如ISAPIRuntime要获取Server
Variable的数据,获取通过Post
Mehod传回Server的数量;以及最终将Response的情节返回给非托管环境ISAPI,然后呈现为Client用户。一般地ISAPIRuntime不克一直调用ISAPI,所以这里虽通过一个靶指针实现对那的调用,这个目标就是是ECB,ECB实现了对非托管环境ISAPI的顾。

非托管环境ISAPI对ISAPIRuntime的调用,需要传递一些要的数额,比如ISAPIRuntime要博取Server
Variable的多少,获取通过Post
Mehod传回Server的多寡;以及尾声以Response的始末返回给非托管环境ISAPI,然后呈现给Client用户。一般地ISAPIRuntime不能够一直调用ISAPI,所以这边就是透过一个目标指针实现对其的调用,这个目标就是ECB,ECB实现了针对非托管环境ISAPI的访。

 

 

还有某些特地需要强调的是,ISAPI对ISAPIRutime的调用是异步的,也就是说ISAPI调用ISAPIRutime之后就回到。这要是出于Performance和Responsibility考虑的,因为ASP.NET
Application天生就是是一个多线程的应用,为了具备更好的响应能力,异步操作是太实惠之化解方式。但是此地就会见出一个问题,我们领略我们本着ASP.NET
资源的调用本质上是一个Request/Response的Message Exchange
Pattern,异步调用往往代表ISAPI将Request传递给ISAPIRuntime,将非能够获得ISAPIRuntime最终生成的Response,这分明是勿可知领之。而ECB解决了此题材,ISAPI在调用ISAPIRutime的ProcessRequest方法时会见用好相应的ECB的指针传于其,ISAPIRutime不但可将最终生成的Response返回给ISAPI,还能经过ECB调用ISAPI获得有所需要的数目。

再有一些特意要强调的凡,ISAPI对ISAPIRutime的调用是异步的,也就是说ISAPI调用ISAPIRutime之后就赶回。这关键是由Performance和Responsibility考虑的,因为ASP.NET
Application天生就是是一个大多线程的利用,为了拥有双重好之应能力,异步操作是绝有效的缓解措施。但是这里就是见面生出一个题目,我们明白我们对ASP.NET
资源的调用本质上是一个Request/Response的Message Exchange
Pattern,异步调用往往意味着ISAPI将Request传递给ISAPIRuntime,将无可知得ISAPIRuntime最终生成的Response,这明摆着是勿能够领之。而ECB解决了这个题目,ISAPI在调用ISAPIRutime的ProcessRequest方法时会拿团结相应的ECB的指针传给它们,ISAPIRutime不但可将最后生成的Response返回给ISAPI,还能够经过ECB调用ISAPI获得有所待的多寡。

 1. CreateWorkerRequest

 1. CreateWorkerRequest

 这个方式还是如果拘留一下的, 有取哦.

 这个办法还是若扣一下底, 有获取哦.

internal static ISAPIWorkerRequest CreateWorkerRequest(IntPtr ecb, bool useOOP)
{
    if (useOOP)
    {
        EtwTrace.TraceEnableCheck(EtwTraceConfigType.DOWNLEVEL, IntPtr.Zero);
        if (EtwTrace.IsTraceEnabled(5, 1))
        {
            EtwTrace.Trace(EtwTraceType.ETW_TYPE_APPDOMAIN_ENTER, ecb, Thread.GetDomain().FriendlyName, null, false);
        }
        return new ISAPIWorkerRequestOutOfProc(ecb);
    }
    int num = UnsafeNativeMethods.EcbGetVersion(ecb) >> 0x10;
    if (num >= 7)
    {
        EtwTrace.TraceEnableCheck(EtwTraceConfigType.IIS7_ISAPI, ecb);
    }
    else
    {
        EtwTrace.TraceEnableCheck(EtwTraceConfigType.DOWNLEVEL, IntPtr.Zero);
    }
    if (EtwTrace.IsTraceEnabled(5, 1))
    {
        EtwTrace.Trace(EtwTraceType.ETW_TYPE_APPDOMAIN_ENTER, ecb, Thread.GetDomain().FriendlyName, null, true);
    }
    if (num >= 7)
    {
        return new ISAPIWorkerRequestInProcForIIS7(ecb);
    }
    if (num == 6)
    {
        return new ISAPIWorkerRequestInProcForIIS6(ecb);
    }
    return new ISAPIWorkerRequestInProc(ecb);
}
internal static ISAPIWorkerRequest CreateWorkerRequest(IntPtr ecb, bool useOOP)
{
    if (useOOP)
    {
        EtwTrace.TraceEnableCheck(EtwTraceConfigType.DOWNLEVEL, IntPtr.Zero);
        if (EtwTrace.IsTraceEnabled(5, 1))
        {
            EtwTrace.Trace(EtwTraceType.ETW_TYPE_APPDOMAIN_ENTER, ecb, Thread.GetDomain().FriendlyName, null, false);
        }
        return new ISAPIWorkerRequestOutOfProc(ecb);
    }
    int num = UnsafeNativeMethods.EcbGetVersion(ecb) >> 0x10;
    if (num >= 7)
    {
        EtwTrace.TraceEnableCheck(EtwTraceConfigType.IIS7_ISAPI, ecb);
    }
    else
    {
        EtwTrace.TraceEnableCheck(EtwTraceConfigType.DOWNLEVEL, IntPtr.Zero);
    }
    if (EtwTrace.IsTraceEnabled(5, 1))
    {
        EtwTrace.Trace(EtwTraceType.ETW_TYPE_APPDOMAIN_ENTER, ecb, Thread.GetDomain().FriendlyName, null, true);
    }
    if (num >= 7)
    {
        return new ISAPIWorkerRequestInProcForIIS7(ecb);
    }
    if (num == 6)
    {
        return new ISAPIWorkerRequestInProcForIIS6(ecb);
    }
    return new ISAPIWorkerRequestInProc(ecb);
}

由此判断ecb和type类型的具体内容,来决定创造什么种的WorkerRequest(上述项目的ISPAIWorkerRequest都蝉联给HttpWorkerRequest),上面的代码可以看来对不同版本的IIS进行了不同之卷入,通过该Initialize方法来初始化一些核心的音信(比如:contentType,
querystring的长,filepath等有关信息)。

由此判断ecb和type类型的具体内容,来控制创造什么品种的WorkerRequest(上述项目的ISPAIWorkerRequest都延续给HttpWorkerRequest),上面的代码可以看看对不同版本的IIS进行了不同之包裹,通过其Initialize方法来初始化一些中坚的音(比如:contentType,
querystring的长短,filepath等相关消息)。

 

 

2. ProcessRequestNoDemand 

2. ProcessRequestNoDemand 

 这个方式, 是真正进入ASP.NET Runtime Pipeline的绝无仅有入口,
传递的参数是者屏蔽了差异化以后的WorkerRequest对象实例.来拘禁一下此点子

 这个法, 是真正进入ASP.NET Runtime Pipeline的绝无仅有入口,
传递的参数是端屏蔽了差异化以后的WorkerRequest对象实例.来拘禁一下这个方法

internal static void ProcessRequestNoDemand(HttpWorkerRequest wr)
{
    RequestQueue queue = _theRuntime._requestQueue;
    wr.UpdateInitialCounters();
    if (queue != null)
    {
        wr = queue.GetRequestToExecute(wr);
    }
    if (wr != null)
    {
        CalculateWaitTimeAndUpdatePerfCounter(wr);
        wr.ResetStartTime();
        ProcessRequestNow(wr);
    }
}
internal static void ProcessRequestNoDemand(HttpWorkerRequest wr)
{
    RequestQueue queue = _theRuntime._requestQueue;
    wr.UpdateInitialCounters();
    if (queue != null)
    {
        wr = queue.GetRequestToExecute(wr);
    }
    if (wr != null)
    {
        CalculateWaitTimeAndUpdatePerfCounter(wr);
        wr.ResetStartTime();
        ProcessRequestNow(wr);
    }
}

Ok, 接下来, 继续看, PRNow方法, 其实内部调用的是
HttpRuntime的 ProcessRequestInternal) 方法.

Ok, 接下来, 继续羁押, PRNow方法, 其实内部调用的是
HttpRuntime的 ProcessRequestInternal) 方法.

爱博体育app手机版 5

爱博体育app手机版 6

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
        {
            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();
            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;
                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);
        }
    }
}
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
        {
            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();
            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;
                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);
        }
    }
}

不过受人开心之, 可能就是是看, 在斯方法吃创造了 HttpContext 对象以及
HttpApplication 对象.

极致受丁开心的, 可能就是是张, 在此主意被创造了 HttpContext 对象及
HttpApplication 对象.

接通下, 分别看一下随即半单对象的创建.

紧接下, 分别看一下当下有限独对象的创建.

1). HttpContext 

1). HttpContext 

internal HttpContext(HttpWorkerRequest wr, bool initResponseWriter)
{
    this._timeoutStartTimeUtcTicks = -1L;
    this._timeoutTicks = -1L;
    this._threadAbortOnTimeout = true;
    this.ThreadContextId = new object();
    this._wr = wr;
    this.Init(new HttpRequest(wr, this), new HttpResponse(wr, this));
    if (initResponseWriter)
    {
        this._response.InitResponseWriter();
    }
    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_EXECUTING);
}
internal HttpContext(HttpWorkerRequest wr, bool initResponseWriter)
{
    this._timeoutStartTimeUtcTicks = -1L;
    this._timeoutTicks = -1L;
    this._threadAbortOnTimeout = true;
    this.ThreadContextId = new object();
    this._wr = wr;
    this.Init(new HttpRequest(wr, this), new HttpResponse(wr, this));
    if (initResponseWriter)
    {
        this._response.InitResponseWriter();
    }
    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_EXECUTING);
}

咱俩还要望了2只惊喜之代码,HttpRequest和HttpResponse的实例化,通过对WorkerRequest和针对性HttpContext对象this参数的传递,将获各自需的音信

我们同时望了2独惊喜之代码,HttpRequest和HttpResponse的实例化,通过对WorkerRequest和针对HttpContext对象this参数的传递,将赢得各自要之音信

 

 

2). HttpApplication 

2). HttpApplication 

斯目标的创造, 是后面那句标红的一些. 

夫目标的创, 是后面那句标红的部分. 

IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);
IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);

经过HttpApplicationFactory的GetApplicationInstance静态方法,获取我们熟悉的HttpApplication对象实例,由于HttpApplication对象是继承IHttpAsyncHandler,而IHttpAsyncHandler又继续给IHttpHandler,所以地方app的型是IHttpHandler是从未错的。继续羁押后的if
(app is
IHttpAsyncHandler)代码,就知了app肯定走这里的分层,然后实施调用asyncHandler.BeginProcessRequest方法了。

经过HttpApplicationFactory的GetApplicationInstance静态方法,获取我们熟悉的HttpApplication对象实例,由于HttpApplication对象是持续IHttpAsyncHandler,而IHttpAsyncHandler又累给IHttpHandler,所以地方app的种是IHttpHandler是从未有过错的。继续羁押后面的if
(app is
IHttpAsyncHandler)代码,就亮了app肯定走这里的子,然后实施调用asyncHandler.BeginProcessRequest方法了。

 

 

迄今,HttpRuntime已经正式发表其无可取代的意向了,也正式通过者目标正式入了HttpApplication对象的创办和大家熟悉的HttpApplication以后的生命周期了。

至今,HttpRuntime已经正式发表其无可取代的图了,也规范通过者目标正式入了HttpApplication对象的创立与大家熟知的HttpApplication以后的生命周期了。

 

 

转载参考:

转载参考:

  MVC之前的那点事

  MVC之前的那么点事儿

目就共

目录就同爱博体育app手机版

相关文章