[译] ASP.NET 生命周期 – ASP.NET 应用生命周期(一)

概述

ASP.NET 平台定义了两个非常重要的生命周期。第一个是 应用生命周期  (application life cycle),用来追踪应用从启动的那一刻到终止的那一刻。另一个就是 请求生命周期 (request life cycle),它定义了 HTTP 请求在 ASP.NET 平台中首次接收到,到最终响应发出之间的路径。

ASP.NET 应用生命周期

在 ASP.NET 中有两个时刻——应用启动的时刻和应用停止接收请求的时刻,这两个时刻定义了应用生命周期。ASP.NET 在应用启动和当应用在可控的情况下停止的时候提供了通知功能,我们接下来就讨论这样的通知功能。

应用生命周期通知允许了我们在应用启动或者应用在可控的情况下停止的时候执行某些任务。如果我们在应用启动的时候需要执行一次性的配置任务或者在应用停止的时候需要释放资源的时候,通知就会变得非常有用。MVC 框架开发者在应用生命周期中最常使用的就是配置一个依赖注入容器。MVC 框架使用应用生命周期来执行与请求相关的配置任务,比如建立 routes, areas, 和 content bundles。

理解应用生命周期

ASP.NET 应用的生命周期从应用启动的那一刻开始,在接收 HTTP 请求并处理生成响应的过程中一直延续。这包括将请求分配到合适的 controllers, actions 上,并从 Razor 视图中渲染内容。生命周期直到应用停止的那一刻结束。

全局应用类在早期版本的 ASP.NET 中就已经存在了,它包含有两个文件:Global.asax 和 Global.asax.cs。严格来讲,Global.asax 文件才是全局应用类,而 Global.asax.cs 文件是与之关联的隐藏代码 (code-behind) 文件。这是一个很经典的 Web Forms 将声明性代码与编程性代码分开的做法,但是现在,这仅仅是为了兼容性,即使在 Web Forms 项目中。下面是 Global.asax 文件中的内容,在 MVC 框架项目中,我们从不需要修改这个文件。

1 <%@ Application Codebehind="Global.asax.cs" Inherits="SimpleApp.MvcApplication" Language="C#" %>

之前版本中遗留下来的 Global.asax 文件多少都会有点有趣,但是,我们关注的重点还是 Global.asax.cs 文件。这个文件的角色在 ASP.NET 进化的过程中也慢慢地改变了,现在 全局应用类 这个术语一般直接用来指 Global.asax.cs 文件了,在解决方案资源管理器中双击 Global.asax 文件直接打开 Global.asax.cs 文件你就可以明白其中缘由了。

下面是案例项目中 Global.asax.cs 文件中的内容:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6 using System.Web.Routing;
 7 
 8 namespace SimpleApp
 9 {
10     public class MvcApplication : System.Web.HttpApplication
11     {
12         protected void Application_Start()
13         {
14             AreaRegistration.RegisterAllAreas();
15             RouteConfig.RegisterRoutes(RouteTable.Routes);
16         }
17     }
18 }

默认的全局应用类叫做 MvcApplication,继承自 System.Web.HttpApplication 类。我们在后面会接触到更多的 System.Web 命名空间下面的类。

MvcApplication 类由 ASP.NET 框架实例化,这里面定义的方法会在应用生命周期的关键时刻被调用。

默认的 MvcApplication 类中只包含了一个方法,叫做 Application_Start,但是还有另外一个方法可用,接下来我们就来介绍。

应用启动和停止的时候接收通知

全局应用类支持两种特殊的方法用来定义应用生命周期的开始与结束:

名称 描述
Application_Start() 当应用启动的时候调用
Application_End() 当应用将要终止的时候调用

Application_Start 方法在应用第一次启动的时候被调用,并且提供了执行一次性配置任务的机会。比如,Visual Studio 在 Application_Start 方法中添加了建立 MVC areas 和 URL routes 的声明。

Application_End方法仅会在应用终结之前执行,提供了释放资源的机会。通常使用这个方法的理由就是释放数据库的连接,但是大多数的现代应用都不直接管理这样的连接,我很少在自己的项目中使用到这个方法。而如今,数据库已经能够足够好的管理它们的连接,而且,Application_End 方法仅会在应用在一个可控制的方式下关闭才会被调用到。因此我们不能够依赖这个方法,因为服务器可能发生不可预知的故障,比如突然断电,这就会导致 Application_End 方法并不会被执行。

我说这些方法是 特殊 的是因为它们实现的方式特别。这些方法并没有定义在全局应用类的基类中 (System.Web.HttpApplication),所以我们并不需要使用 override 关键字来实现它们。事实上,ASP.NET 框架使用反射的方式根据方法名称来检索它们。如果你写错了方法的名称并不会得到任何的错误提示,ASP.NET 会假设你在应用开始或者结束的时候不想得到通知。正因为这样,测试并确保你的代码能够被执行是非常重要的。

提示:有时候,我们在 Application_Start 和 Application_End 方法的定义中看到 Object 和 EventArgs 参数,这是为了遵循 C# 事件处理器方法的约定。这是可选的,ASP.NET 框架能够定位到那些有这两个参数或者没有参数的方法。

[译] ASP.NET 生命周期 – ASP.NET 应用生命周期(一)

图 1 - 应用生命周期

测试启动和停止通知

我们可以在应用中直接使用 Application_Start 和 Application_End 方法来执行一次性的启动和关闭任务。接下来,我将会教大家怎么使用调试器来确保者两个方法能够被执行——特别是在我们自定义代码不能够像我们预期的那样执行的时候显得格外重要。

最简单的方法来测试这些方法是否被执行就是使用 Visual Studio 的调试器,下面的代码片段中,我们会看到怎么在 Application_start 和 Application_End 方法中调用添加的静态 System.Diagnostics.Debugger.Break 方法,这和我们在 Visual Studio 代码编辑器中直接设置一个断点的效果是一样的。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6 using System.Web.Routing;
 7 
 8 namespace SimpleApp
 9 {
10     public class MvcApplication : System.Web.HttpApplication
11     {
12         protected void Application_Start()
13         {
14             AreaRegistration.RegisterAllAreas();
15             RouteConfig.RegisterRoutes(RouteTable.Routes);
16             System.Diagnostics.Debugger.Break();
17         }
18 
19         protected void Application_End()
20         {
21             System.Diagnostics.Debugger.Break();
22         }
23     }
24 }

测试启动通知

测试 Application_Start 方法是非常简单的,在 Visual Studio 调试菜单中选择启动调试,Visual Studio 会打开一个浏览器窗口。ASP.NET 框架开始初始化这个应用,创建了一个全局应用类的实例,发现了 Application_Start 方法,然后调用它,这将会引起 Break 方法被调用。应用的执行将会暂停,控制将会传递给调试器,如下图所示:

[译] ASP.NET 生命周期 – ASP.NET 应用生命周期(一)

图 2 - Application_Start 方法调用的时候控制传递给调试器

在调试菜单中选择继续,应用的执行将会恢复。来自浏览器的请求将会被处理,并生成相应的 HTML 响应发送给用户。

测试停止通知

测试 Application_End 方法有一点点困难,因为如果选择停止调试将会导致在 Application_End 方法被调用之前调试器将会从应用上分离出去。浏览器窗口关闭,调试器终止掉,Visual Studio 将会返回到默认的状态——然而,Debugger.Break 方法并没有被调用。

为了测试 Application_End 中的代码,我们必须直接使用 IIS Express,而非通过 Visual Studio。IIS Express 是 Visual Studio 中自带的一个简化版的 IIS 应用服务器,只是用于在开发过程中运行 ASP.NET 应用的。

在 Windows 任务栏中定位到 IIS Express 图标,右击它会有一个弹窗菜单出现。在菜单项目中,我们会看到一个 SimpleApp 项目(应用名称),当你选中它的时候会看到一个停止站点菜单项目,如下图所示:

[译] ASP.NET 生命周期 – ASP.NET 应用生命周期(一)

图 3 - 使用 IIS Express 停止一个应用

当选择停止站点的时候,IIS Express 会停止这个应用,作为处理过程的一部分,Application_End方法将会被调用。在本例中,Debugger.Break 方法将会被调用,如下图所示:

[译] ASP.NET 生命周期 – ASP.NET 应用生命周期(一)

图 4 - 测试 Application_End 方法中的代码

 

[根据 Adam Freeman – Pro ASP.NET MVC 5 Platform 选译]

上一篇:JAVA实现拼图游戏


下一篇:控制器 - 控制器面面观(三)