首页 > 编程 > .NET > 正文

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

2024-07-10 13:12:39
字体:
来源:转载
供稿:网友
在这里我们有一个在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扩展的非托管操作。

,欢迎访问网页设计爱好者web开发。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表