不管使用哪种底层平台,可靠性和性能都是对所有 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 的默认进程模型,即 Microsof
t? Internet Information Services (IIS) 5.x 中唯一的模型。
ASP.NET 结构的组件
执行 ASP.NET 应用程序需要宿主 Web 服务器的支持。在 Microsoft? Window
s? 的 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 和辅助进程之间的通讯是使用一组命名管道进行的。命名管道是一种 W
in32 机制,用于跨进程边界传输数据。顾名思义,命名管道的工作方式与管道相似
:在一端输入数据,在另一端输出相同的数据。建立的管道既可以连接本地进程,
也可以连接远程计算机上运行的进程。对于本地进程间通讯,管道是 Windows 中的
最有效、最灵活的工具。
为确保获得最优性能,aspnet_isapi 使用异步命名管道来将请求转发给辅助进
程并获得响应。另一方面,辅助进程在需要查询有关 IIS 环境的信息(即服务器变
量)时又使用同步管道。aspnet_isapi 模块创建固定数量的命名管道,并使用重叠
的操作以通过小的线程池处理同一时间进行的连接。当通过管道进行的数据交换操
作结束后,完成例程将断开客户端,并重新使用管道实例为新的客户端服务。线程
池和重叠操作均可以保证使 ASP.NET ISAPI 的性能达到令人满意的水平。但是,a
spnet_isapi 扩展决不会处理 HTTP 请求。
ASP.NET 请求的处理逻辑可以概括为以下步骤:
当请求到达时,IIS 检查资源类型并调用 ASP.NET ISAPI 扩展。如果启用了默
认的进程模型,aspnet_isapi 会将请求排队,并将请求分配给辅助进程。所有的请
求数据都通过异步 I/O 发送。如果启用了 IIS 6 进程模型,请求将自动在辅助进
程 (w3wp.exe) 中排队,此辅助进程用于处理应用程序所属的 IIS 应用程序池。I
IS 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) 的功能的控制。进程回收具有 as
pnet_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.NE
T 应用程序的无 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 模型,它们是 webG
arden 和 cpuMask。webGarden 属性接受布尔值,表示是否使用了多个辅助进程(
一个相关的 CPU 对应一个进程)。默认情况下,该属性的值为 false。cpuMask 属
性保存一个 DWORD 值,该值的二进制表示为能够运行 ASP.NET 辅助进程的 CPU 提
供了位屏蔽。其默认值为 -1 (0xFFFFFF),表示可以使用所有可用的 CPU。如果 w
ebGarden 属性为 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 服务器将根据选择的身份验证模型(匿名、W
indows、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 对象初始化一系列有助于实现请求的内部对象。Help
er 对象包括缓存管理器(Cache 对象)和内部文件系统监视器(用于检测构成应用
程序的源文件的更改)。HttpRuntime 为请求创建上下文,并用与请求相关的 HTT
P 信息填充上下文。上下文用 HttpContext 类的实例来表示。
另一个在 HTTP 运行时的设置初期创建的 Helper 对象是文本书写器,用于包
含浏览器的响应文本。文本书写器是 HttpWriter 类的实例,此对象对页面代码以
编程方式发送的文本进行缓存。HTTP 运行时被初始化后,它将查找实现请求的应用
程序对象。应用程序对象是 HttpApplication 类的实例,该类就是 global.asax
文件背后的类。global.asax 在编程时是可选的,但在构建结构时是必需的。因此
,如果应用程序中没有构建类,则必须使用默认对象。ASP.NET 运行时包括几个中
间工厂类,可以用来查找并返回有效的 Handler 对象以处理请求。整个过程中用到
的第一个工厂类是 HttpApplicationFactory。它的主要任务是使用 URL 信息来查
找 URL 虚拟目录和汇集的 HttpApplication 对象之间的匹配关系。
应用程序工厂类的行为可以概括为以下几点:
工厂类维护 HttpApplication 对象池,并使用它们来处理应用程序的请求。池
的寿命与应用程序的寿命相同。
应用程序的第一个请求到达时,工厂类提取有关应用程序类型的信息(global
.asax 类)、设置用于监视更改的文件、创建应用程序状态并触发 Application_O
nStart 事件。
工厂类从池中获取一个 HttpApplication 实例,并将要处理的请求放入实例中
。如果没有可用的对象,则创建一个新的 HttpApplication 对象。要创建 HttpAp
plication 对象,需要先完成 global.asax 应用程序文件的编译。
HttpApplication 开始处理请求,并且只能在完成这个请求后才能处理新的请
求。如果收到来自同一资源的新请求,则由池中的其他对象来处理。
应用程序对象允许所有注册的 HTTP 模块对请求进行预处理,并找出最适合处
理请求的处理程序类型。这通过查找请求的 URL 的扩展和配置文件中的信息来完成
。
HTTP 处理程序是一些实现 IHttpHandler 接口的类。.NET Framework 为常见
的资源类型提供了一些预定义的处理程序,包括 ASPX 页面和 Web 服务。machine
.config 文件中的 <httpHandlers> 部分定义了 HttpApplication 对象必须实例
化才能处理特定类型资源的请求的类名。如果 Helper 类是一个处理程序工厂,Ge
tHandler 方法将确定要使用的处理程序类型。这时,将从一组类似的对象中获取适
当类型的处理程序,并对其进行配置以处理请求。
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 Bas
ic? .NET 类中,但可以将 Web 页面编写和部署为 .aspx 文本文件。对于要显示为
URL 的页面来说,.aspx 文件在应用程序的 Web 空间中必须始终可用。.aspx 文
件的实际内容将确定应用程序对象要加载的程序集(或多个程序集)。
按照设计,HttpApplication 对象将查找一个根据请求的 ASPX 文件命名的类
。如果页面命名为 sample.aspx,则要加载的相应的类名为 ASP.sample_aspx。应
用程序对象在 Web 应用程序的所有程序集文件夹中查找这样的类,这些文件夹包括
全局程序集缓存 (GAC)、Bin 子文件夹和 Temporary ASP.NET Files 文件夹。如果
未找到这样的类,HTTP 结构将分析 .aspx 文件的源代码,创建一个 C# 或 Visua
l Basic .NET 类(具体创建哪种类,取决于 .aspx 页面上设置的语言),同时对
其进行编译。新创建的程序集的名称是随机生成的,位于特定于应用程序的子文件
夹中,路径如下所示: C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Tempor
ary 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 文件的内容,应用程序对象就
可以了解要加载的程序集的名称以及要在其中获取的类。以下代码片段是这种 Hel
per 文件的典型内容。包含 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 Fr
amework 中,您无法卸载单个程序集。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 进
程模型之间的最新区别。
转载于:https://www.cnblogs.com/akein/archive/2008/11/04/1326735.html