按照设计,HttpApplication 对象将查找一个根据请求的 ASPX 文件命名的类。如果页面命名为 sample.aspx,则要加载的相应的类名为 ASP.sample_aspx。应用程序对象在 Web 应用程序的所有程序集文件夹中查找这样的类,这些文件夹包括全局程序集缓存 (GAC)、Bin 子文件夹和 Temporary ASP.NET Files 文件夹。如果未找到这样的类,HTTP 结构将分析 .aspx 文件的源代码,创建一个 C# 或 Visual Basic .NET 类(具体创建哪种类,取决于 .aspx 页面上设置的语言),同时对其进行编译。新创建的程序集的名称是随机生成的,位于特定于应用程序的子文件夹中,路径如下所示: C:WINDOWSMicrosoft.NETFrameworkv1.1.4322Temporary 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:inetpubwwwrootvdirsample.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 进程模型之间的最新区别。