zoukankan      html  css  js  c++  java
  • [转]ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline

    相信大家都使用过ASP.NET进行过基于Web的应用开发,ASP.NET是什么?如果站在一个相对High Level的角度,我们可以这样来定义ASP.NETASP.NET是一个基于Web的开发平台,提供构建企业级应用所需的ServiceProgramming ModelSoftwareInfrastructure。如果我们以一个Low Level的角度来看,它本质上就是一个消息处理器:他接受IIS(确切地说应该是ASP.NET ISAPIForwardHttp Request (我们可以看成是一个Request Message),经过一系列的处理,最终产生一个用户希望的Response(这也是一个Message,对于.aspx Page来说是一个Html document,对于一个Web Service来说是一个Soap)。所以本篇文章的主要目的在于站在一个相对Low Level的角度介绍ASP.NET的整个Http Request Processing Model。我们访问一个基于ASP.NET的资源,IIS是第一道屏障,在第一个部分我分别就IIS 5.xIIS 6的差异介绍了IISHttp Request的处理,今天我们来继续后面的故事。

    一、从Unmanaged Environment到Managed Environment

    上一部分我们说到IIS收到一个基于ASP.NET资源文件的访问,它会把Http Request交给一个ASP.NET ISAPI Extension处理。ASP.NET ISAPI 会加载CLR,从而创建一个托管的环境。ASP.NET ISAPI Extension定义在一个名为aspnet_isapi.dll中,aspnet_isapi.dll是一个纯Native的、高效的Dll,也就是说,虽然ASP.NET ISAPI通过加载CLR创建一个托管的环境,但是ASP.NET ISAPI本省却运行在一个Unmanaged的环境中。而我们的ASP.NET Application确是完全的Managed code,运行在一个Managed的环境中。要了解ASP.NET Http Runtime Pipeline这个纯托管的Runtime,我们必须先了解从Unmanaged EnvironmentManaged Environment的这道桥梁。



    上图简单表述了在
    IIS 6环境下,从非托管环境到托管环境的过程。从图中我们可以看到,ASP.NET ISAPI运行在一个非托管环境之中。ASP.NET ISAPI经过系列COM级别的class调用(由于这些被调用的Class都是一个个undocumented class,所以要真正说清楚调用流程中每个具体的细节是一件很难的事情,而且也确实没有很大的必要去挖掘它,因为具体的实现可能会经常变动,如果对此具有好奇心的朋友可以通过一些Tool,比如Reflector去仔细研究一下),最终的调用降临到一个托管的、继承自System.Web.Hosting.ISAPIRuntime类的对象上。ISAPIRuntime 是一个特殊的class,他实现了Interface System.Web.Hosting.IISAPIRuntime。下面是该Interface的定义。通过定义我们可以看到,这是一个基于COMInterface,也就是说Caller可以通过COM的方式调用实现该InterfaceClass的对象。在这里,这个最初的Caller就是ASP.NET ISAPI。从这里我们可以总结出:ASP.NET ISAPI通过调用System.Web.Hosting.ISAPIRuntime Instance
    ProcessRequest方法,进而从非托管的环境进入了托管的环境。

    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("08a2c56f-7c16-41c1-a8be-432917a1a2d1")]
    public interface IISAPIRuntime
    {
        
    void StartProcessing();
        
    void StopProcessing();
        [
    return: MarshalAs(UnmanagedType.I4)]
        
    int ProcessRequest([In] IntPtr ecb, [In, MarshalAs(UnmanagedType.I4)] int useProcessModel);
        
    void DoGCCollect();
    }

    ISAPI ECB (Execution Control Block) & ISAPIWorkerRequest

    通过System.Web.Hosting.IISAPIRuntime Interface中的ProcessRequest方法的Siganature,我们可以看出该方法包含两个参数,其中一个是名为ecbUnmanaged Pointer,另一个是useProcessModelECB全称是Execution Control Block,在整个Http Request Processing过程中起着非常重要的作用,我们现在来简单介绍一个ECB

    ISAPI顾名思义,就是实现了一些基于Internet ServerAPIAspnet_isapi.dll实现了这些API,对于IIS来说,它可以调用这些API进入托管的环境实现对ISAPIRuntime的调用,对于ISAPIRuntime来说,它需要调用ASP.NET ISAPI实现一些必要的功能,比如获得Server Variable的数据,获得通过Post Mehod传回Server的数据;以及最终将Response的内容返回给ASP.NET ISAPI,并通过ASP.NET ISAPI返回到Client。一般地ISAPIRuntime不能直接调用ASP.NET ISAPI,而是通过一个对象指针实现对其的调用,这个对象就是ECBECB实现了对ISAPI的访问。

    还有一点特别需要强调的是,ISAPIISAPIRutime的调用是异步的,也就是说ISAPI调用ISAPIRutime之后立即返回。这主要是出于PerformanceResponsibility考虑的,因为ASP.NET Application天生就是一个多线程的应用,为了具有更好的响应能力,异步操作是最有效的解决方式。但是这里就会有一个问题,我们知道我们对ASP.NET 资源的调用本质上是一个Request/ResponseMessage Exchange Pattern,异步调用往往意味着ISAPIRequest传递给ISAPIRuntime,将不能得到ISAPIRuntime最终生成的Response,这显然是不能接受的。而ECB解决了这个问题,ISAPI在调用ISAPIRutimeProcessRequest方法时会将自己对应的ECB的指针传给它,ISAPIRutime不但可以将最终生成的Response返回给ISAPI,还能通过ECB调用ISAPI获得一些所需的数据。

    明白ECB是怎么回事之后,我们通过Reflector简单了解一下ISAPIRutimeProcessRequest的实现:

    ProcessRequest

    对于上面的代码,我觉得没有必要去深究,但是对于那些具有强烈好奇心的朋友除外J。基本上上面的代码完成下面两个任务:

    通过传入的ECBiWRType创建一个叫做ISAPIWorkerRequest的对象:

    bool useOOP = iWRType == 1;
    wr 
    = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);

    然后调用HttpRuntime.ProcessRequestNoDemand(wr)通过将创建的ISAPIWorkerRequest的对象作为参数传入。

    HttpRuntime.ProcessRequestNoDemand的调用真正进入了ASP.NET Runtime Pipeline,这是一个相对复杂的过程。在这里我想简单说说ISAPIWorkerRequest这个重要classISAPIWorkerRequest是一个Abstract class,它已通过ECB创建基于当前RequestContext的信息,针对不同的IIS版本,具有不同的ISAPIWorkerRequest subclass,比如:ISAPIWorkerRequestOutOfProcIIS 5.x, ISAPIWorkerRequestInProcForIIS6, ISAPIWorkerRequestInProcForIIS7ProcessRequest通过ISAPI传入的iWRType来创建不同HttpWorkerRequest,从而屏蔽了不同IIS的差异,后续的步骤就不需要考虑这种差异了,这是Abstract Factory的典型用法。

    通过 ASP.NET Http Runtime Pipeline - Part II 进入第二部分。

    Reference:
    A low-level Look at the ASP.NET Architecture

    ASP.NET Process Model
    [原创]ASP.NET Process Model之一:IIS 和 ASP.NET ISAPI
    [原创]ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline - Part I
    [原创]ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline - Part II

    作者:Artech
    出处:http://artech.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    LeetCode 326. Power of Three
    LeetCode 324. Wiggle Sort II
    LeetCode 322. Coin Change
    LeetCode 321. Create Maximum Number
    LeetCode 319. Bulb Switcher
    LeetCode 318. Maximum Product of Word Lengths
    LeetCode 310. Minimum Height Trees (DFS)
    个人站点大开发!--起始篇
    LeetCode 313. Super Ugly Number
    LeetCode 309. Best Time to Buy and Sell Stock with Cooldown (DP)
  • 原文地址:https://www.cnblogs.com/joe1545134/p/asp-net-http-runtime-pipeline-part-i.html
Copyright © 2011-2022 走看看