不管使用哪种底层平台,可靠性和性能都是对所有;Web;应用程序的主要要求,尽管从某种意义上讲,这两个要求是相互矛盾的。例如,要构建更可靠、更健壮的应用程序,可能需要将;Web;服务器与具体的应用程序分离,使应用程序在进程外工作。但是,如果在不同于;Web;服务器进程的内存环境中工作,应用程序将变慢。因此,需要采取合理的措施,以确保进程外代码尽可能快地运行。;
在构建;Microsoft?;ASP.NET;运行时环境时,依据的设计原则即:充分考虑可靠性和性能。得到的;ASP.NET;进程模型包含了两个系统元素;-;一个存在于;Web;服务器进程中的进程内连接器,一个外部的辅助进程。另外,ASP.NET;运行时结构的可伸缩能力很强,可以自动使用多处理器硬件中任意选定的处理器。这种模式被称为“Web;Garden”,它可以使多个辅助进程同时运行,而且各个进程均在独立的处理器中。;
高度概括起来,ASP.NET;运行时具有三大属性:;
应用程序和;ASP.NET;辅助进程之间完全分离。提供服务的辅助进程的寿命决不会影响应用程序的寿命。换句话说,当应用程序启动并处于运行状态时,辅助进程可以随时终止。;
尽管;ASP.NET;应用程序从不在;Web;服务器内采用进程内的方式运行,但大多数情况下,其总体性能仍接近于进程内应用程序的性能。;
为;Web;Garden;体系结构提供了内置的和可配置的支持。只要简单检查一下配置文件中的设置,辅助进程就可以克隆自己,以利用所有与进程密切相关的;CPU。因此,在大多数情况下,您在具备多处理器的计算机中获得的可缩放性将呈线性增长的趋势。(本文后面将详细介绍此内容。);
本文将介绍;ASP.NET;运行时环境的组成元素,然后一步一步地讲述从;URL;请求变为纯;HTML;文本的“漫长而曲折”的过程。;
除非另有说明,否则以下介绍中均指;ASP.NET;的默认进程模型,即;Microsoft?;Internet;Information;Services;(IIS);5.x;中唯一的模型。;
ASP.NET;结构的组件;
执行;ASP.NET;应用程序需要宿主;Web;服务器的支持。在;Microsoft?;Windows?;的;Server;平台中,Web;服务器由名为;inetinfo.exe;的;IIS;可执行文件表示。Windows;2000;及以上版本的操作系统本身均提供了;Web;服务器。但需要注意,在;Microsoft?;Windows;Server™;2003;中,并未默认安装;IIS;和;ASP.NET,必须通过单击“控制面板”中的“添加或删除程序”小程序将其添加到系统中。;
IIS;是一个未托管的可执行程序,它提供了一个基于;ISAPI;扩展模块和筛选器模块的可扩展模型。通过编写此类模块,开发人员可以直接管理对特定资源类型的请求,并在各个预定义的步骤中接收当前请求。扩展和筛选器是一些;DLL,可以导出一些具有已知名称和签名的函数。这些插件组件是在;IIS;配置数据库中注册并配置的。;
;
只有少数几种被客户端请求的资源类型由;IIS;直接处理。例如,对;HTML;页面、文本文件、JPEG;和;GIF;图像的传入请求由;IIS;处理。对;Active;Server;Page;(*.asp);文件的请求通过调用名为;asp.dll;的;ASP;专用扩展模块进行解析。同样,对;ASP.NET;资源(例如,*.aspx、*.asmx、*.ashx)的请求将传递到;ASP.NET;ISAPI;扩展。该系统组件是一个名为;aspnet_isapi.dll;的;Win32;DLL。ASP.NET;扩展可以处理多种资源类型,包括;Web;服务和;HTTP;处理程序调用。;
ASP.NET;ISAPI;扩展是一个;Win32;DLL,未集成托管代码。它是接收和分派对各种;ASP.NET;资源的请求的控制中心。按照设计,该模块存在于;IIS;进程中,在具有管理员权限的;SYSTEM;帐户下运行。开发人员和系统管理员不能修改此帐户。ASP.NET;ISAPI;扩展负责调用;ASP.NET;辅助进程;(aspnet_wp.exe),而该进程又负责控制请求的执行。除了对请求进行安排以外,ASP.NET;ISAPI;还监视辅助进程的运行情况,并在性能降低到一定程度时将进程取消。;
辅助进程是一小段;Win32;shell;代码,集成了公共语言运行库;(CLR);并运行托管代码。它负责处理对;ASPX、ASMX;和;ASHX;资源的请求。一般来说,此进程在一台给定的计算机中只有一个实例。所有当前激活的;ASP.NET;应用程序均在其中运行,每个应用程序都位于一个独立的;AppDomain;中。但是,如前所述,辅助进程支持;Web;Garden;模式,即进程的相同副本都运行在与进程密切相关的;CPU;中。(更多内容,请参阅本文后面的“Web;Garden;模型”部分。);
ISAPI;和辅助进程之间的通讯是使用一组命名管道进行的。命名管道是一种;Win32;机制,用于跨进程边界传输数据。顾名思义,命名管道的工作方式与管道相似:在一端输入数据,在另一端输出相同的数据。建立的管道既可以连接本地进程,也可以连接远程计算机上运行的进程。对于本地进程间通讯,管道是;Windows;中的最有效、最灵活的工具。;
为确保获得最优性能,aspnet_isapi;使用异步命名管道来将请求转发给辅助进程并获得响应。另一方面,辅助进程在需要查询有关;IIS;环境的信息(即服务器变量)时又使用同步管道。aspnet_isapi;模块创建固定数量的命名管道,并使用重叠的操作以通过小的线程池处理同一时间进行的连接。当通过管道进行的数据交换操作结束后,完成例程将断开客户端,并重新使用管道实例为新的客户端服务。线程池和重叠操作均可以保证使;ASP.NET;ISAPI;的性能达到令人满意的水平。但是,aspnet_isapi;扩展决不会处理;HTTP;请求。;
ASP.NET;请求的处理逻辑可以概括为以下步骤:;
当请求到达时,IIS;检查资源类型并调用;ASP.NET;ISAPI;扩展。如果启用了默认的进程模型,aspnet_isapi;会将请求排队,并将请求分配给辅助进程。所有的请求数据都通过异步;I/O;发送。如果启用了;IIS;6;进程模型,请求将自动在辅助进程;(w3wp.exe);中排队,此辅助进程用于处理应用程序所属的;IIS;应用程序池。IIS;6;辅助进程不了解;ASP.NET;和托管代码的任何情况,它只是处理;*.aspx;扩展并加载;aspnet_isapi;模块。当;ASP.NET;ISAPI;在;IIS;6;进程模型中运行时,它的工作方式有所不同,仅在;w3wp.exe;辅助进程的上下文中加载;CLR。;
收到请求后,ASP.NET;辅助进程将通知;ASP.NET;ISAPI,它将为请求服务。通知通过同步;I/O;实现。之所以使用同步模型,是因为请求只有在;ISAPI;内部请求表中被标记为“executing”,辅助进程才能开始处理它。如果请求已经由特殊的辅助进程进行处理,则不能再将它指定到其他进程,除非原始进程已取消。;
在辅助进程的上下文中执行请求。有时,辅助进程可能需要回调;ISAPI;以完成请求,也就是需要说枚举服务器变量。这种情况下,辅助进程将使用同步管道,因为这样可以保持请求处理逻辑的顺序。;
完成后,响应被发送到打开了异步管道的;aspnet_isapi。现在,请求的状态变为“Done”,之后将从请求表中被删除。如果辅助进程崩溃,正在处理的所有请求仍将保持“executing”状态并持续一段时间。如果;aspnet_isapi;检测到辅助进程已取消,它将自动终止请求并释放所有相关的;IIS;资源。;
以上说明是指默认的;ASP.NET;进程模型,即在;IIS;5.x;中运行的工作模型。IIS;6(Windows;Server;2003;提供)的默认工作方式对;ASP.NET;进程模型也有影响。当集成在;IIS;6.0;中时,ASP.NET;1.1;会自动调整自己的工作方式以适应宿主环境。这时,不再需要使用;aspnet_wp;辅助进程,machine.config;文件中定义的某些配置参数也被忽略。从;ASP.NET;的角度来看,IIS;6;的最大改变是有关请求的一切都在;aspnet_isapi;的控制之下,且都处在;w3wp.exe;辅助进程的上下文中。辅助进程的帐户是为;Web;应用程序所属的应用程序池设置的帐户。默认情况下,该帐户是;NETWORKSERVICE―,它是一个内置的弱帐户,在功能上与;ASPNET;等价。;
辅助进程受一个名为进程回收;(Recycling);的功能的控制。进程回收具有;aspnet_isapi;功能,当现有进程消耗的内存太多、响应太慢或挂起时可以自动启动新进程。出现这种情况时,新请求将由新实例处理,新实例从而变成新的活动进程。但是,指定给旧进程的所有请求仍保持挂起状态。如果旧进程结束了挂起的请求并进入空闲状态,该进程即终止。如果辅助进程崩溃,或者由于其他原因停止处理请求,则所有挂起的请求将被重新指定给新进程。;
尽管;ASP.NET;ISAPI;和辅助进程是;ASP.NET;运行时结构的主要组成部分,但还有其他一些可执行文件也发挥着作用。下表列出了所有这些组件。;
表;1:构成;ASP.NET;运行时环境的可执行文件;
名称;类型;帐户?;
aspnet_isapi.dll;Win32;DLL(ISAPI;扩展);LOCAL;SYSTEM?;
aspnet_wp.exe;Win32;EXE;ASPNET;
aspnet_filter.dll;Win32;DLL(ISAPI;筛选器);LOCAL;SYSTEM?;
aspnet_state.exe;Win32;NT;Service;ASPNET;
aspnet_filter.dll;组件是一个小的;Win32;ISAPI;筛选器,用来备份;ASP.NET;应用程序的无;Cookie;会话状态。在;Windows;Server;2003;中,当启用;IIS;6;进程模型时,aspnet_filter.dll;还将筛选出;Bin;目录中对非可执行资源的请求。;
aspnet_state.exe;的作用对;Web;应用程序更为重要,因为它用于管理会话状态。该项服务是可选的,可以用来在;Web;应用程序内存空间之外保存会话状态数据。该可执行文件是一种;NT;服务,既可以在本地运行,也可以远程运行。当该服务被激活后,可以将;ASP.NET;应用程序配置为将所有会话信息保存在此进程的内存中。一种类似的方案是提供更为可靠的数据存储方式,不受进程回收和;ASP.NET;应用程序故障的影响。该服务在;ASPNET;本地帐户下运行,但可以使用服务控制管理器;(Service;Control;Manager);接口来配置它。;
另一个应该介绍的可执行文件是;aspnet_regiis.exe,尽管严格来讲,它并不属于;ASP.NET;运行时结构。该实用程序可以用来配置环境,以在一台计算机上并行执行不同版本的;ASP.NET,还可用于维修;IIS;和;ASP.NET;损坏的配置。该实用程序的工作方式是更新存储在;IIS;配置数据库的根目录和子目录中的脚本映射。脚本映射是资源类型和;ASP.NET;模块之间的一种关联关系。最后,还可以使用该工具来显示已安装的;ASP.NET;版本的状态,执行其他配置操作,如授予对特定文件夹的;NTFS;权限、创建客户脚本目录。;
Web;Garden;模型;
Web;Garden;模型可以通过;machine.config;文件中的;<processModel>;部分进行配置。请注意,<processModel>;部分是唯一不能放在应用程序特定的;web.config;文件中的配置部分。这就是说,Web;Garden;模式可以应用到计算机中运行的所有应用程序。但通过使用;machine.config;源文件中的;<location>;节点,可以针对各个应用程序调节计算机的设置。;
<processModel>;部分有两个属性可以影响;Web;Garden;模型,它们是;webGarden;和;cpuMask。webGarden;属性接受布尔值,表示是否使用了多个辅助进程(一个相关的;CPU;对应一个进程)。默认情况下,该属性的值为;false。cpuMask;属性保存一个;DWORD;值,该值的二进制表示为能够运行;ASP.NET;辅助进程的;CPU;提供了位屏蔽。其默认值为;-1;(0xFFFFFF),表示可以使用所有可用的;CPU。如果;webGarden;属性为;false,则;cpuMask;属性的内容将被忽略。cpuMask;属性还为正在运行的;aspnet_wp.exe;的副本数设置了上限。;
常言道“闪光的不都是金子”,用在这里很合适。Web;Garden;模式使得多个辅助进程可以同时运行。但是,需要注意的是所有进程都会有自己的应用程序状态、进程内会话状态、ASP.NET;缓存、静态数据以及运行应用程序所需的其他内容。启用;Web;Garden;模式之后,ASP.NET;ISAPI;将根据;CPU;的数量尽可能多地启动辅助进程,每个辅助进程都是下一进程的完整克隆(每一进程都与相应的;CPU;密切相关)。为平衡工作负荷,传入的请求以单循环的方式在运行的进程之间进行划分。辅助进程就象在单处理器中一样被回收。请注意,ASP.NET;继承了操作系统中所有的;CPU;使用限制,并且不包括实现限制的自定义语义。;
总之,Web;Garden;模型并不适用于所有应用程序。应用程序的状态越多,其的性能损失也越多。工作数据存储在共享内存的块中,以便一个进程输入的变化可以立即被其他进程得知。但是,处理请求时,工作数据被复制到进程的上下文中。因此,各个辅助进程将处理自己的工作数据,而应用程序的状态越多,性能损失就越大。鉴于此,仔细、明智的应用程序基准测试是绝对必要的。;
只有重启;IIS;后,对配置文件中;<processModel>;部分所做的更改才会生效。在;IIS;6;中,Web;Garden;模式的参数保存在;IIS;配置数据库中,webGarden;和;cpuMask;属性被忽略。;
HTTP;管道;
ASP.NET;ISAPI;扩展启动辅助进程后,它将传递部分命令行参数。辅助进程使用这些参数来执行加载;CLR;前需要执行的任务。传递的值包括:COM;和;DCOM;安全性所要求的身份验证等级、可以使用的命名管道的数量和;IIS;进程标识。命名管道的名称是使用;IIS;进程标识和允许的管道数随机生成的。辅助进程不接收可用管道的名称,但可以接收识别管道名称所需的信息。;
COM;和;DCOM;安全性与;Microsoft?;.NET;Framework;有何关系?实际上,CLR;是作为;COM;对象提供的。更准确地说,CLR;本身不是由;COM;代码构成的,但是指向;CLR;的接口却是一个;COM;对象。因此,辅助进程加载;CLR;的方式与加载;COM;对象的方式相同。;
当;ASPX;请求遇到;IIS;时,Web;服务器将根据选择的身份验证模型(匿名、Windows、Basic;或;Digest)来分配一个令牌。当辅助进程收到要处理的请求时,令牌被传递到辅助进程。请求由辅助进程中的线程获取。该线程从最初获取传入请求的;IIS;线程继承身份令牌。在;aspnet_wp.exe;中,负责处理请求的实际帐户取决于在特殊的;ASP.NET;应用程序中是如何配置模拟的。如果模拟被禁用(默认设置),则线程将在辅助进程的帐户下运行。默认情况下,该帐户在;ASP.NET;进程模型中为;ASPNET,在;IIS;6;进程模型中为;NETWORKSERVICE。这两个帐户都是“弱”帐户,提供的功能比较有限,可以有效抵挡回复性攻击;(Revert-to-self;Attack)。(回复性攻击是指将模拟的客户端的安全性令牌回复到父进程令牌。为辅助进程分配弱帐户可以挫败此类攻击。);
高度概括起来,ASP.NET;辅助进程完成的一项主要任务就是将请求交给一系列称为的;HTTP;管道的托管对象。要激活;HTTP;管道,可以创建一个;HttpRuntime;类的新实例,然后调用其;ProcessRequest;方法。如前所述,ASP.NET;中始终只运行一个辅助进程(除非启用了;Web;Garden;模型),该进程在独立的;AppDomain;中管理所有的;Web;应用程序。每个;AppDomain;都有自己的;HttpRuntime;类实例,即管道中的输入点。HttpRuntime;对象初始化一系列有助于实现请求的内部对象。Helper;对象包括缓存管理器(Cache;对象)和内部文件系统监视器(用于检测构成应用程序的源文件的更改)。HttpRuntime;为请求创建上下文,并用与请求相关的;HTTP;信息填充上下文。上下文用;HttpContext;类的实例来表示。;
另一个在;HTTP;运行时的设置初期创建的;Helper;对象是文本书写器,用于包含浏览器的响应文本。文本书写器是;HttpWriter;类的实例,此对象对页面代码以编程方式发送的文本进行缓存。HTTP;运行时被初始化后,它将查找实现请求的应用程序对象。应用程序对象是;HttpApplication;类的实例,该类就是;global.asax;文件背后的类。global.asax;在编程时是可选的,但在构建结构时是必需的。因此,如果应用程序中没有构建类,则必须使用默认对象。ASP.NET;运行时包括几个中间工厂类,可以用来查找并返回有效的;Handler;对象以处理请求。整个过程中用到的第一个工厂类是;HttpApplicationFactory。它的主要任务是使用;URL;信息来查找;URL;虚拟目录和汇集的;HttpApplication;对象之间的匹配关系。;
应用程序工厂类的行为可以概括为以下几点:;
工厂类维护;HttpApplication;对象池,并使用它们来处理应用程序的请求。池的寿命与应用程序的寿命相同。;
应用程序的第一个请求到达时,工厂类提取有关应用程序类型的信息(global.asax;类)、设置用于监视更改的文件、创建应用程序状态并触发;Application_OnStart;事件。;
工厂类从池中获取一个;HttpApplication;实例,并将要处理的请求放入实例中。如果没有可用的对象,则创建一个新的;HttpApplication;对象。要创建;HttpApplication;对象,需要先完成;global.asax;应用程序文件的编译。;
HttpApplication;开始处理请求,并且只能在完成这个请求后才能处理新的请求。如果收到来自同一资源的新请求,则由池中的其他对象来处理。;
应用程序对象允许所有注册的;HTTP;模块对请求进行预处理,并找出最适合处理请求的处理程序类型。这通过查找请求的;URL;的扩展和配置文件中的信息来完成。;
HTTP;处理程序是一些实现;IHttpHandler;接口的类。.NET;Framework;为常见的资源类型提供了一些预定义的处理程序,包括;ASPX;页面和;Web;服务。machine.config;文件中的;<httpHandlers>;部分定义了;HttpApplication;对象必须实例化才能处理特定类型资源的请求的类名。如果;Helper;类是一个处理程序工厂,GetHandler;方法将确定要使用的处理程序类型。这时,将从一组类似的对象中获取适当类型的处理程序,并对其进行配置以处理请求。;
IHttpHandler;接口提供了两个方法:IsReusable;和;ProcessRequest。前者将返回一个布尔值,表示处理程序是否可以被汇集。(大多数预定义的处理程序都是汇集的,但是您可以自行定义每次都需要新实例的处理程序。)ProcessRequest;方法包含处理特定类型资源所需的所有逻辑。例如,ASPX;页面的处理程序基于以下伪代码:;
private;void;ProcessRequest();
{;
//;确定请求是否是回发;(postback);
IsPostBack;=;DeterminePostBackMode();;
//;触发;ASPX;源代码的;Page_Init;事件;
PageInit();;
//;加载;ViewState,处理已发送的值。;
if;(IsPostBack);{;
LoadPageViewState();;
ProcessPostData();;
};
//;触发;ASPX;源代码的;Page_Load;事件;
PageLoad();;
//;1);再次处理已发送的值(当;
//;动态创建控件时);
//;2);将属性更改的服务器端事件提升为输入驱动的;
//;控件(即复选框的状态改变);
//;3);执行与回发事件相关的所有代码;
if;(IsPostBack);{;
ProcessPostDataSecondTry();;
RaiseChangedEvents();;
RaisePostBackEvent();;
};
//;触发;ASPX;源代码的;Page_PreRender;事件;
PreRender();;
//;将控件的当前状态保存到;ViewState;中;
SavePageViewState();;
//;将页面内容呈现给;HTML;
RenderControl(CreateHtmlTextWriter(Response.Output));;
};
无论调用的资源类型如何,基于;HTTP;处理程序的模型是相同的。唯一随资源类型变化而变化的元素是处理程序。HttpApplication;对象负责查找应该使用哪种处理程序来处理请求。HttpApplication;对象还负责检测对动态创建的、表示资源的程序集(如;.aspx;页面或;.asmx;Web;服务)所进行的更改。如果检测到更改,应用程序对象将确保编译并加载所请求的资源的最新来源。;
临时文件和页面程序集;
要全面了解;ASP.NET;HTTP;运行时,让我们来分析一下当请求;ASP.NET;页面时,文件系统层所发生的变化。接下来,您将了解由;HTTP;管道的对象管理和监视的一组动态创建的临时文件。;
虽然可以将页面的核心代码隔离在代码背后的;C#;或;Microsoft?;Visual;Basic?;.NET;类中,但可以将;Web;页面编写和部署为;.aspx;文本文件。对于要显示为;URL;的页面来说,.aspx;文件在应用程序的;Web;空间中必须始终可用。.aspx;文件的实际内容将确定应用程序对象要加载的程序集(或多个程序集)。;
按照设计,HttpApplication;对象将查找一个根据请求的;ASPX;文件命名的类。如果页面命名为;sample.aspx,则要加载的相应的类名为;ASP.sample_aspx。应用程序对象在;Web;应用程序的所有程序集文件夹中查找这样的类,这些文件夹包括全局程序集缓存;(GAC)、Bin;子文件夹和;Temporary;ASP.NET;Files;文件夹。如果未找到这样的类,HTTP;结构将分析;.aspx;文件的源代码,创建一个;C#;或;Visual;Basic;.NET;类(具体创建哪种类,取决于;.aspx;页面上设置的语言),同时对其进行编译。新创建的程序集的名称是随机生成的,位于特定于应用程序的子文件夹中,路径如下所示:;C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary;ASP.NET;Files。;
子文件夹;v1.1.4322;特定于;ASP.NET;1.1。如果您使用的是;ASP.NET;1.0,子文件夹的版本号会有所不同,即子文件夹名为;v1.0.3705。再次访问页面时,程序集就已存在,不需要重新创建。但是,HttpApplication;对象是如何确定特定于页面的程序集是否存在呢?它每次都要扫描大量文件夹吗?不,并不是这样。;
应用程序对象只查看;Temporary;ASP.NET;Files;文件夹中某个特殊文件夹的内容。具体路径(特定于应用程序的路径)由;HttpRuntime.CodegenDir;属性返回。如果是第一次访问;.aspx;文件(即还未创建页面程序集),则该文件夹中就不存在以;ASPX;页面名称开头的;XML;文件。例如,具有动态程序集的;sample.aspx;页面应有如下的条目:;
sample.aspx.XXXXX.xml;
XXXXX;占位符是一种散列代码。通过读取该;XML;文件的内容,应用程序对象就可以了解要加载的程序集的名称以及要在其中获取的类。以下代码片段是这种;Helper;文件的典型内容。包含;ASP.sample_aspx;类的程序集的名称是;mvxvx8xr。;
<preserve;assem="mvxvx8xr";type="ASP.sample_aspx">;
<filedep;name="c:/inetpub/wwwroot/vdir/sample.aspx";/>;
</preserve>;
当然,只有在分析;filedep;文件的源代码以生成动态程序集时才创建该文件。对;filedep;文件所做的任何更改都会使程序集无效,在下一次请求时必须重新编译。需要注意的是,在;ASP.NET;架构的未来版本中,该实现过程可能会有较大改变。不论什么原因,只要您决定在当前应用程序中使用它,都必须十分小心。;
由于更新而要为页面创建新的程序集时,ASP.NET;将验证是否可以删除旧的程序集。如果旧的程序集只包含修改后的页面的类,ASP.NET;将试图删除并替换该程序集,否则将在保留旧程序集的情况下创建一个新程序集。;
在删除过程中,ASP.NET;可能会发现程序集文件已被加载并锁定。这种情况下,可以为旧程序集添加一个“.DELETE”扩展名,以将其重新命名。(注意,所有;Windows;文件都可以在使用过程中重新命名。)只要应用程序重新启动(例如,由于对某个应用程序文件如;global.asax;和;web.config;进行了更改),这些临时的;.DELETE;文件就将被删除。但在处理下一个请求时,ASP.NET;运行时不会删除这些文件。;
请注意,默认情况下,在整个应用程序重新启动之前,每个;ASP.NET;应用程序最多可以重新编译;15;个页面,同时会损失一些会话和应用程序数据。当最近的编译次数超过了;<httpRuntime>;部分的;numRecompilesBeforeAppRestart;属性中设置的阈值时,将卸载;AppDomain,并重新启动应用程序。还要注意,在;.NET;Framework;中,您无法卸载单个程序集。AppDomain;是可以从;CLR;卸载的最小的代码块。;
小结;
ASP.NET;应用程序有两大特征:进程模型和页面对象模型。ASP.NET;提前使用了;IIS;6.0;的一些功能,而;IIS;6.0;则是;Windows;Server;2003;中提供的全新的、开创性的;Microsoft;Web;信息服务。尤其值得一提的是,在独立的辅助进程中运行的;ASP.NET;应用程序,其行为与;IIS;6;中的所有应用程序相同。而且,尽管会出现运行时异常、内存泄露或程序错误,ASP.NET;运行时仍能自动回收辅助进程以保证实现卓越的性能。这种功能已成为;IIS;6.0;的系统功能。;
在本文中,我概括介绍了默认的;ASP.NET;进程模型的基础知识,以及;IIS;级代码(ASP.NET;ISAPI;扩展)和辅助进程之间的交互。同时,还介绍了与;IIS;6;进程模型之间的最新区别。;
标签: