[译] 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 框架项目中,我们从不需要修改这个文件。
<%@ 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 文件中的内容:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing; namespace SimpleApp
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
}
默认的全局应用类叫做 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 框架能够定位到那些有这两个参数或者没有参数的方法。
图 1 - 应用生命周期
测试启动和停止通知
我们可以在应用中直接使用 Application_Start 和 Application_End 方法来执行一次性的启动和关闭任务。接下来,我将会教大家怎么使用调试器来确保者两个方法能够被执行——特别是在我们自定义代码不能够像我们预期的那样执行的时候显得格外重要。
最简单的方法来测试这些方法是否被执行就是使用 Visual Studio 的调试器,下面的代码片段中,我们会看到怎么在 Application_start 和 Application_End 方法中调用添加的静态 System.Diagnostics.Debugger.Break 方法,这和我们在 Visual Studio 代码编辑器中直接设置一个断点的效果是一样的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing; namespace SimpleApp
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
System.Diagnostics.Debugger.Break();
} protected void Application_End()
{
System.Diagnostics.Debugger.Break();
}
}
}
测试启动通知
测试 Application_Start 方法是非常简单的,在 Visual Studio 调试菜单中选择启动调试,Visual Studio 会打开一个浏览器窗口。ASP.NET 框架开始初始化这个应用,创建了一个全局应用类的实例,发现了 Application_Start 方法,然后调用它,这将会引起 Break 方法被调用。应用的执行将会暂停,控制将会传递给调试器,如下图所示:
图 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 项目(应用名称),当你选中它的时候会看到一个停止站点菜单项目,如下图所示:
图 3 - 使用 IIS Express 停止一个应用
当选择停止站点的时候,IIS Express 会停止这个应用,作为处理过程的一部分,Application_End方法将会被调用。在本例中,Debugger.Break 方法将会被调用,如下图所示:
图 4 - 测试 Application_End 方法中的代码
[根据 Adam Freeman – Pro ASP.NET MVC 5 Platform 选译]
[译] ASP.NET 生命周期 – ASP.NET 应用生命周期(一)的更多相关文章
- [译] ASP.NET 生命周期 – ASP.NET 上下文对象(五)
ASP.NET 上下文对象 ASP.NET 提供了一系列对象用来给当前请求,将要返回到客户端的响应,以及 Web 应用本身提供上下文信息.间接的,这些上下文对象也可以用来回去核心 ASP.NET 框架 ...
- .net学习笔记---Asp.net的生命周期之二页生命周期
用户请求 从 用户角度来说,我不管你后台经历了什么,我只想要我请求的页面.请求到服务器端,服务器必须得有所表示的是吧,即使不想搭理人家也得让IIS给人家说声:找不到服务器.请求来到服务器端,肯定要让服 ...
- ASP.NET Web 应用程序及页面生命周期
以客户端浏览器向 ASP.NET Web 应用程序页面发送请求(Request)为起点,以浏览器收到 Web 服务器的响应(Response)为终点,这一完整的过程被称为"应用程序及页面的生 ...
- 【深入ASP.NET原理系列】--ASP.NET请求管道、应用程序生命周期、整体运行机制
微软的程序设计和相应的IDE做的很棒,让人很快就能有生产力..NET上手容易,生产力很高,但对于一个不是那么勤奋的人,他很可能就不再进步了,没有想深入下去的动力,他不用去理解整个框架和环境是怎么执行的 ...
- atitit.提升开发效率---使用服务器控件生命周期 asp.net 11个阶段 java jsf 的6个阶段比较
atitit.提升开发效率---使用服务器控件生命周期 asp.net 11个阶段 java jsf 的6个阶段比较 如下列举了服务器控件生命周期所要经历的11个阶段. (1)初始化-- --在此 ...
- .net学习笔记----Asp.net的生命周期之一应用程序生命周期
Http请求刚刚到达服务器的时候 当服务器接收到一个 Http请求的时候,IIS (Internet Information Services,互联网信息服务)首先需要决定如何去处理这个请求. 什么是 ...
- Asp.net的生命周期之应用程序生命周期
参考:http://msdn.microsoft.com/zh-cn/library/ms178473(v=vs.100).aspx 参考:http://www.cnblogs.com/JimmyZh ...
- atitit.提升开发效率---使用server控件生命周期 asp.net 11个阶段 java jsf 的6个阶段比較
atitit.提升开发效率---使用server控件生命周期 asp.net 11个阶段 java jsf 的6个阶段比較 例如以下列举了server控件生命周期所要经历的11个阶段. (1)初始 ...
- ASP.NET请求管道、应用程序生命周期、整体运行机制
我们知道在ASP.NET中,若要对ASP.NET应用程序进行 初始化并使它处理请求,必须执行一些处理步骤,熟悉应用程序生命周期非常重要,这样才能在适当的生命周期阶段编写代码,达到预期的效果.永远不要做 ...
随机推荐
- centos搭建本地库
--2013年8月23日11:00:26环境:centos6.3(64bit)--场景默认情况下在用yum install 安装软件会从配置库中下载依赖包默认依赖库:来自网络在本地搭建依赖库可以节约带 ...
- javaweb学习总结五(内省、beanUtils工具包)
一:内省的概念 1:内省是反射的一种特例,由于在反射中频繁的操作javabean,所以为了方便反射 javabean,sun公司开发出一套API提高效率. 2:javaBean,就是用来封装客户端请求 ...
- Url几个常用的函数
parse_url() 本函数解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分. 本函数不是用来验证给定 URL 的合法性的,只是将其分解为下面列出的部分.不完整的 URL ...
- HTML5 indexedDB数据库的入门学习(一)
笔者早些时间看过web sql database,但是不再维护和支持,所以最近初步学习了一下indexedDB数据库,首先indexedDB(简称IDB)和web sql database有很大的差别 ...
- cvSaveImage的第三个参数
http://stackoverflow.com/questions/801054/opencv-cvsaveimage-jpeg-compression-factor #define CV_IM ...
- JavaScript设置cookie
在做网站的时候会用到JS操作cookie,现在写下来,算是对自己工作的一次小小总结,后面用到的时候就不用再写一遍了,高手就不用看了. /* 添加cookie 参数:cookie名,cookie值,过期 ...
- Linux命令(6):mv命令
1.作用: 为文件或目录改名或将文件由一个目录移入另一个目录中 2.格式: mv [选项] 源文件或目录 目标文件或目录 3.常见参数: 4.使用实例: [root@localhost ~]# mv ...
- php中preg_match用户名正则实例
例子,字母.数字和汉字 代码如下 复制代码 if(preg_match("/[ '.,:;*?~`!@#$%^&+=)(<>{}]|]|[|/|\|"||/& ...
- CSS 元素垂直居中的 6种方法
利用CSS进行元素的水平居中,比较简单,行级元素设置其父元素的text-align center,块级元素设置其本身的left 和 right margins为auto即可.本文收集了六种利用css进 ...
- javascript笔记——jikeytang javascript前端群 389875212 精华总结
网址: https://github.com/jsfront // http://www.kancloud.cn/jsfront/month/82796 内容: 前端js github总结, ...