分享
 
 
 

ASP.NET底层架构探索之进入.NET运行时

王朝asp·作者佚名  2008-05-30
窄屏简体版  字體: |||超大  

进入.NET运行时的真正的入口发生在一些没有被文档记载的类和接口中(译著:当然,你可以用Reflector来查看J).除了微软,很少人知道这些接口,微软的家伙们也并不热衷于谈论这些细节,他们认为这些实现细节对于使用asp.net开发应用的开发人员并没有什么用处。

工作进程(IIS5中是ASPNET_WP.EXE,IIS6中是W3WP.EXE)寄宿.NET运行时和ISAPI DLL,它(工作进程)通过调用COM对象的一个小的非托管接口最终将调用发送到ISAPIRuntime类的一个实例上(译注:原文为an instance subclass of the ISAPIRuntime class,但是ISAPIRuntime类是一个sealed类,疑为作者笔误,或者这里的subclass并不是子类的意思).进入运行时的第一个入口就是这个没有被文档记载的类,这个类实现了IISAPIRuntime接口(对于调用者说明来说,这个接口是一个COM接口)这个基于Iunknown的底层COM接口是从ISAPI扩展到ASP.NET的一个预定的接口.图3展示了IISAPIRuntime接口和它的调用签名.(使用了Lutz Roeder出色的.NET Reflector 工具http://www.aisto.com/roeder/dotnet/).这是一个探索这个步步为营过程的很好的方法.

图3-如果你想深入这个接口,打开Reflector,指向System.Web.Hosting命名空间. ISAPI DLL通过调用一个托管的COM接口来打开进入ASP.NET的入口,ASP.NET接收一个指向ISAPI ECB的非托管指针.这个ECB包含访问完整的ISAPI接口的能力,用来接收请求和发送响应回到IIS.

IISAPIRuntime接口作为从ISAPI扩展来的非托管代码和ASP.NET之间的接口点(IIS6中直接相接,IIS5中通过命名管道).如果你看一下这个类的内部,你会找到含有以下签名的PRocessRequest函数:

[return: MarshalAs(UnmanagedType.I4)]

int ProcessRequest([In] IntPtr ecb,

[In, MarshalAs(UnmanagedType.I4)] int useProcessModel);

其中的ecb参数就是ISAPI扩展控制块(Extention Control Block),被当作一个非托管资源传递给ProcessRequest函数.这个函数接过ECB后就把它做为基本的输入输出接口,和Request和Response对象一起使用.ISAPI ECB包含有所有底层的请求信息,如服务器变量,用于表单(form)变量的输入流和用于回写数据到客户端的输出流.这一个ecb引用基本上提供了用来访问ISAPI请求所能访问的资源的全部功能,ProcessRequest是这个资源(ecb)最初接触到托管代码的入口和出口.

ISAPI扩展异步地处理请求.在这个模式下ISAPI扩展马上将调用返回到工作进程或者IIS线程上,但是在当前请求的生命周期上ECB会保持可用.ECB含有使ISAPI知道请求已经被处理完的机制(通过ecb.ServerSupportFunction方法)(译注:更多信息,可以参考开发ISAPI扩展的文章),这使得ECB被释放.这个异步的处理方法可以马上释放ISAPI工作线程,并将处理传递到由ASP.NET管理的一个单独的线程上.

ASP.NET接收到ecb引用并在内部使用它来接收当前请求的信息,如服务器变量,POST的数据,同样它也返回信息给服务器.ecb在请求完成前或超时时间到之前都保持可访问(stay alive),这样ASP.NET就可以继续和它通讯直到请求处理完成.输出被写入ISAPI输出流(使用ecb.WriteClient())然后请求就完成了,ISAPI扩展得到请求处理完成的通知并释放ECB.这个实现是非常高效的,因为.NET类本质上只是对高效的、非托管的ISAPI ECB的一个非常”瘦”(thin)的包装器.

装载.NET-有点神秘

让我们从这儿往回退一步:我跳过了.NET运行时是怎么被载入的.这是事情变得有一点模糊的地方.我没有在这个过程中找到任何的文档,而且因为我们在讨论本机代码,没有很好的办法来反编译ISAPI DLL并找出它(装载.NET运行时的代码)来.

我能作出的最好的猜测是当ISAPI扩展接受到第一个映射到ASP.NET的扩展名的请求时,工作进程装载了.NET运行时.一旦运行时存在,非托管代码就可以为指定的虚拟目录请求一个ISAPIRuntime的实例(如果这个实例还不存在的话).每个虚拟目录拥有它自己的应用程序域(AppDomain),当一个独立的应用(指一个ASP.NET程序)开始的时候ISAPIRuntime从启动过程就一直在应用程序域中存在.实例化(译注:应该是指ISAPIRuntime的实例化)似乎是通过COM来进行的,因为接口方法都被暴露为COM可调用的方法.

当第一个针对某虚拟目录的请求到来时,System.Web.Hosting.AppDomainFactory.Create()函数被调用来创建一个ISAPIRuntime的实例.这就开始了这个应用的启动进程.这个调用接收这个应用的类型,模块名称和虚拟目录信息,这些信息被ASP.NET用来创建应用程序域并启动此虚拟目录的ASP.NET程序.这个HttpRuntime实例(译注:原文为This HttpRuntime derived object,但HttpRuntime是一个sealed类,疑为原文错误)在一个新的应用程序域中被创建.每个虚拟目录(即一个ASP.NET应用程序寄)宿在一个独立的应用程序域中,而且他们也只有在特定的ASP.NET程序被请求到的时候才会被载入.ISAPI扩展管理这些HttpRuntime对象的实例,并根据请求的虚拟目录将内部的请求路由到正确的那个HttpRuntime对象上.

图4-ISAPI请求使用一些没有文档记载的类,接口并调用许多工厂方法传送到ASP.NET的HTTP管道的过程.每个Web程序/虚拟目录在它自己的应用程序域中运行,调用者(译注:指ISAPI DLL)保持一个IISAPIRuntime接口的引用来触发ASP.NET的请求处理.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有