现在的位置: 首页 > 综合 > 正文

ASP.NET 运行模式

2013年01月12日 ⁄ 综合 ⁄ 共 2292字 ⁄ 字号 评论关闭

在访问者于浏览器上键入网址链接至IIS后,IIS会根据访问者所要求的文件扩展名来启动对应IIS Extension程序处理此要求,这个文件扩展名的对应表可以通过IIS所提供的Internet管理员程序来修改。

我们选择PageHandlerFactory-ISAPI-2.0,右击,然后选择编辑,就会看到下面的页面:

由上图可以得知,扩展名.aspx文件所对应的ISAPI Extension是aspnet_isapi.dll,这个文件位于.NET Framework的安装目录中,预设是%windir%\Microsoft.NET\Framework\vxxxx。aspnet_isapi.dll在此处扮演的是一个入口的角色,实际上,处理访问者要求的是其背后的aspnet_wp.exe,.NET将这个程序统称为ASP.NET Work Process(以下简称WP),此文件同样位于.NET Framework安装目录中。当aspnet_isapi.dll收到有IIS所转交的访问者要求时,会将此要求通过named
pipe协议转送给运行中的WP程序,此时WP会解出要求中的虚拟目录信息来决定创建一个新的AppDomain对象或是使用先前已创建好的AppDomain对象来处理此要求,理论上每一个虚拟目录都对应着一个AppDomain对象,不过在系统内存拮据的情况下,WP会随着系统内存耗损情况来选择是否释放闲置的AppDomain对象,让系统能容纳跟多的访问者。当WP发现要求文件所在的虚拟目录并未拥有对应的AppDomain对象时,WP会创建一个新的AppDomain对象后加载asp.net执行时期所需要的Assemblys及访问者所要求的文件,也就是.aspx文件,下图展示了这个流程。

在载入.aspx文件的动作中隐含着很多技术(在网上找了一张具有代表性的图),如下图所示:

 

 

 

WP接到来自aspnet_isapi.dll的要求后,会将要求转送到虚拟目录对应的Applicatioin Domain中的ISAPIRuntime对象,此对象主要功能是由ISAPI封包中解出信息后转交给HttpRuntime对象,在解出必要的信息后,ISAPIRuntime对象接着调用HttpRuntime.ProcessRequest函数来处理用户要求,此函数中会创建一个HttpContext对象,HttpRuntime对象会将取自ISAPIRuntime对象中的访问信息填入该对象。由整体结构上来看,HttpRuntime对象管理着HttpContext与Cache对象,而HttpContext对象则管理着一个HttpSession对象,每一个访问者要求都对应着一个HttpContext对象,因此每一个访问者自然就拥有独立的HttpSession对象了。在创建HttpContext对象后,随之创建的是HttpApplication对象,此对象时经由HttpApplicationFactory对象创建的,当HttpRuntime对象向HttpApplicationFactory对象要求一个HttpApplication对象时,HttpApplicationFactory对象会先解译目录中的Global.asax文件,接着加载虚拟目录内的Application
Assembly(Global.dll),而后合并两者创建出一个Ghost Application Class,最后编译此Class后取得对象实例后返回至HttpRuntime对象,这个对象实例就是HttpApplication对象。解译与编译.asax文件的动作只发生于此虚拟目录第一次处理用户要求,或是Global.asax、Global.dll在前次执行后又做了变动时。取得HttpApplication对象实例后,HttpRuntime对象紧着调用HttpApplication.ProcessRequest函数,此函数会将执行权转交至对应的HttpHandler对象上。在初始化HttpApplication对象期间,相关的HttpModules会被加载,HttpModules指的是Applicatioin层级的模块,如Session、Authenticaiton等模块,每个HttpModule都必须实现IHttpModule接口,下面的代码是IHttpModule接口原型。

namespace System.Web
{
    public interface IHttpModule
    {
        void init(HttpApplication context);
        void Dispose();
    }
}

    其中的init函数会在HttpApplication对象加载该模块时被调用,一般实现中通常会在此函数中挂载事件处理函数至HttpApplication对象所提供的事件上,借此取得这些时间发生时的主导权,例如SessionState Module就拦截了HttpApplication.BeginRequest/EndRequest等事件来处理Session。Dispose函数则是在HttpModule被释放时调用,这里通常是撰写释放内存的程序代码。一般设计人员撰写HttpModule的情况不多,多半是用于提供额外的认证或是服务性质等功能。本文所描述的动作大多是设计人员无法介入的,甚至难以得知其实际的运作模式,其中与设计人员相关联密切的是Ghost
Applicatioin Class的创建过程,这是asp.net如何结合编译与解译两种技术的关键。

 

抱歉!评论已关闭.