首页 > 编程 > .NET > 正文

ASP.NET底层架构探索之再谈.NET运行时

2024-07-10 13:09:38
字体:
来源:转载
供稿:网友
  • 本文来源于网页设计爱好者web开发社区http://www.html.org.cn收集整理,欢迎访问。
  •   在这里我们有一个在isapi扩展中活动的,可调用的isapiruntime对象的实例。每次运行时是启动的并运行着的时候(译注:相对的,如果运行时并没有启动,就需要象上一章所说的那样载入运行时),isapi的代码调用isapiruntime.processrequest()方法,这个方法是真正的进入asp.net管道的入口,这个流程在图4中显示。

      记住isapi是多线程的,所以请求也会通过appdomainfactory.create()(译注:原文为applicationdomainfactory,疑有误)函数中返回的引用在多线程环境中被处理.列表1显示了isapiruntime.processrequest()方法中反编译后的代码,这个方法接收一个isapi ecb对象和服务类型(workerrequesttype)作为参数.这个方法是线程安全的, 所以多个isapi线程可以同时在这一个被返回的对象实例上安全的调用这个方法。

      列表1:processrequest方法接收一个isapi ecb并将其传给工作线程

    public int processrequest(intptr ecb, int iwrtype)
    {
     httpworkerrequest request1 = isapiworkerrequest.createworkerrequest(ecb,  iwrtype);
     string text1 = request1.getapppathtranslated();
     string text2 = httpruntime.appdomainapppathinternal;
     if (((text2 == null) || text1.equals(".")) ||
      (string.compare(text1, text2, true, cultureinfo.invariantculture) == 0))
     {
      httpruntime.processrequest(request1);
      return 0;
     }
     httpruntime.shutdownappdomain("physical application path changed from " +text2 + " to " + text1);
     return 1;
    }

      这里实际的代码并不重要, 记住这是从内部框架代码中反编译出来的, 你不能直接处理它, 它也有可能在将来发生改变.它只是用来揭示在幕后发生了什么.processrequest方法接收非托管的ecb引用并将它传送给isapiworkerrequest对象, 此对象负责为当前请求创建创建请求上下文.在列表2中显示了这个过程.

      system.web.hosting.isapiworkerrequest类是httpworkerrequest类的一个抽象子类(译注:httpworkerrequest和isapiworkerrequest都是抽象类, 并且isapiworkerrequest继承自httpworkerrequest),它的工作是构建一个作为web应用输入的输入输出的抽象视角。注意这里有另一个工厂方法:createworkerrequest, 通过判断接受到的第二个参数来创建对应的workerrequest对象.有三个不同的版本:isapiworkerrequestinproc,isapiworkerrequestinprocforiis6, isapiworkerrequestoutofproc.每次有请求进入,这个对象被创建并作为请求和响应对象的基础,它会接收它们的数据和由workerrequest提供的数据流.

      抽象的httpworkerrequest类在低层接口上提供一个高层的抽象,这样就封装了数据是从哪里来的,可以是一个cgi web服务器,web浏览器控件或者是一些你用来给http运行时”喂”数据的自定义的机制.关键是asp.net能用统一的方法来接收信息。

      在使用iis的情况下, 这个抽象是建立在isapi ecb块周围.在我们的请求处理过程中, isapiworkerrequest挂起isapi ecb并根据需要从它那里取出信息.列表2显示了请求字符串值(query string value)是如何被取出来的.

      列表2:使用非托管数据的isapiworkerrequest方法

    // *** implemented in isapiworkerrequest

    public override byte[] getquerystringrawbytes()
    {
     byte[] buffer1 = new byte[this._querystringlength];
     if (this._querystringlength > 0)
     {
      int num1 = this.getquerystringrawbytescore(buffer1, this._querystringlength);
      if (num1 != 1)
      {
       throw new httpexception( "cannot_get_query_string_bytes");
      }
     }
     return buffer1;
    }
    // *** implemented in a specific implementation class isapiworkerrequestinprociis6

    internal override int getquerystringcore(int encode,stringbuilder buffer, int size)
    {
     if (this._ecb == intptr.zero)
     {
      return 0;
     }
     return unsafenativemethods.ecbgetquerystring(this._ecb,encode,buffer,size);
    }

      isapiworkerrequest实现了一个高层次的包装方法, 它调用了低层的核心方法, 负责真正的访问非托管apis-或称为”服务级别的实现”(service level implementation).这些核心方法在特殊的isapiworkerrequest子类中为它寄宿的环境提供特殊的实现, 这实现了简单的扩展的(pluggable)环境, 这样一来当以后新的web服务器接口或其他平台成为了asp.net的目标时附加的实现类可以在被简单的提供出来。这里还有一个协助类(helper class)system.web.unsafenativemethods.里面许多对isapi ecb结构的操作实现了对isapi扩展的非托管操作。
    发表评论 共有条评论
    用户名: 密码:
    验证码: 匿名发表