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

简介: 概述 ASP.NET 平台定义了两个非常重要的生命周期。第一个是 应用生命周期  (application life cycle),用来追踪应用从启动的那一刻到终止的那一刻。另一个就是 请求生命周期 (request life cycle),它定义了 HTTP 请求在 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 框架能够定位到那些有这两个参数或者没有参数的方法。

3.1 The application life cycle

图 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 方法被调用。应用的执行将会暂停,控制将会传递给调试器,如下图所示:

3.2 Control is passed to the debugger when the Application_Start method is called

图 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.3 Stopping an application using IIS Express

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

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

3.4 Testing the code in the Application_End method

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

 

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

相关文章
|
1月前
|
存储 Shell Linux
快速上手基于 BaGet 的脚本自动化构建 .net 应用打包
本文介绍了如何使用脚本自动化构建 `.net` 应用的 `nuget` 包并推送到指定服务仓库。首先概述了 `BaGet`——一个开源、轻量级且高性能的 `NuGet` 服务器,支持多种存储后端及配置选项。接着详细描述了 `BaGet` 的安装、配置及使用方法,并提供了 `PowerShell` 和 `Bash` 脚本实例,用于自动化推送 `.nupkg` 文件。最后总结了 `BaGet` 的优势及其在实际部署中的便捷性。
77 10
|
2月前
|
Linux C++ Windows
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
|
1月前
|
开发框架 前端开发 .NET
VB.NET中如何利用ASP.NET进行Web开发
在VB.NET中利用ASP.NET进行Web开发是一个常见的做法,特别是在需要构建动态、交互式Web应用程序时。ASP.NET是一个由微软开发的开源Web应用程序框架,它允许开发者使用多种编程语言(包括VB.NET)来创建Web应用程序。
47 5
|
1月前
|
数据采集 JSON API
.NET 3.5 中 HttpWebRequest 的核心用法及应用
【9月更文挑战第7天】在.NET 3.5环境下,HttpWebRequest 类是处理HTTP请求的一个核心组件,它封装了HTTP协议的细节,使得开发者可以方便地发送HTTP请求并接收响应。本文将详细介绍HttpWebRequest的核心用法及其实战应用。
86 6
|
2月前
|
Linux iOS开发 开发者
跨平台开发不再难:.NET Core如何让你的应用在Windows、Linux、macOS上自如游走?
【8月更文挑战第28天】本文提供了一份详尽的.NET跨平台开发指南,涵盖.NET Core简介、环境配置、项目结构、代码编写、依赖管理、构建与测试、部署及容器化等多个方面,帮助开发者掌握关键技术与最佳实践,充分利用.NET Core实现高效、便捷的跨平台应用开发与部署。
110 3
|
2月前
|
缓存 Java API
【揭秘】.NET高手不愿透露的秘密:如何让应用瞬间提速?
【8月更文挑战第28天】本文通过对比的方式,介绍了针对 .NET 应用性能瓶颈的优化方法。以一个存在响应延迟和并发处理不足的 Web API 项目为例,从性能分析入手,探讨了使用结构体减少内存分配、异步编程提高吞吐量、EF Core 惰性加载减少数据库访问以及垃圾回收机制优化等多个方面,帮助开发者全面提升 .NET 应用的性能和稳定性。通过具体示例,展示了如何在不同场景下选择最佳实践,以实现更高效的应用体验。
38 3
|
2月前
|
前端开发 JavaScript 开发工具
跨域联姻:React.NET——.NET应用与React的完美融合,解锁前后端高效协作新姿势。
【8月更文挑战第28天】探索React.NET,这是将热门前端框架React与强大的.NET后端无缝集成的创新方案。React以其组件化和虚拟DOM技术著称,能构建高性能、可维护的用户界面;.NET则擅长企业级应用开发。React.NET作为桥梁,使.NET应用轻松采用React构建前端,并优化开发流程与性能。通过直接托管React组件,.NET应用简化了部署流程,同时支持服务器端渲染(SSR),提升首屏加载速度与SEO优化。
41 1
|
2月前
|
存储 缓存 安全
.NET 在金融行业的应用:高并发交易系统的构建与优化之路
【8月更文挑战第28天】在金融行业,交易系统需具备高并发处理、低延迟及高稳定性和安全性。利用.NET构建此类系统时,可采用异步编程提升并发能力,优化数据库访问以降低延迟,使用缓存减少数据库访问频率,借助分布式事务确保数据一致性,并加强安全性措施。通过综合优化,满足金融行业的严苛要求。
44 1
|
2月前
|
大数据 开发工具 开发者
从零到英雄:.NET核心技术带你踏上编程之旅,构建首个应用,开启你的数字世界探险!
【8月更文挑战第28天】本文带领读者从零开始,使用强大的.NET平台搭建首个控制台应用。无论你是新手还是希望扩展技能的开发者,都能通过本文逐步掌握.NET的核心技术。从环境搭建到创建项目,再到编写和运行代码,详细步骤助你轻松上手。通过计算两数之和的小项目,你不仅能快速入门,还能为未来开发更复杂的应用奠定基础。希望本文为你的.NET学习之旅开启新篇章!
32 1
|
2月前
|
数据库 C# 开发者
WPF开发者必读:揭秘ADO.NET与Entity Framework数据库交互秘籍,轻松实现企业级应用!
【8月更文挑战第31天】在现代软件开发中,WPF 与数据库的交互对于构建企业级应用至关重要。本文介绍了如何利用 ADO.NET 和 Entity Framework 在 WPF 应用中访问和操作数据库。ADO.NET 是 .NET Framework 中用于访问各类数据库(如 SQL Server、MySQL 等)的类库;Entity Framework 则是一种 ORM 框架,支持面向对象的数据操作。文章通过示例展示了如何在 WPF 应用中集成这两种技术,提高开发效率。
45 0