ASP.NET 使用 Dispose 释放资源的四种方法
Dispose 和 Finalize 是运行的 .NET 和 .NET Core 应用程序释放占用的资源的两种方法。通常,如果应用程序中有非托管资源,应该显式地释放这些资源占用的资源。
由于 Finalize 的非确定性,以及在性能方面的成本很高,因此 Dispose 方法的使用频率远高于 Finalize。其实,我们可以在一个实现了 IDisposable 接口的类型上使用 Dispose 方法。
本文中提供的代码示例均默认运行在 Visual Studio 2022。
1. 使用 VS2022 创建 ASP.NET Core 项目
我们在 Visual Studio 2022 中创建一个 ASP.NET Core 项目。按照以下步骤在 Visual Studio 2022 中创建一个新的 ASP.NET Core Web API 6 项目。
- 1) 启动 Visual Studio 2022 IDE。
- 2) 单击 “Create new project”。
- 3) 在 “Create new project” 窗口中,从显示的模板列表中选择 “ASP.NET Core Web API”。
- 4) 点击下一步。
- 5) 在 “Configure your new project” 窗口中,指定新项目的名称和位置。
- 6) 根据您的偏好,可选择选中 “Place solution and project in the same directory” 复选框。
- 7) 点击下一步。
- 8) 在接下来显示的 “Additional Information” 窗口中,从顶部的下拉列表中选择 .NET 6.0 作为目标框架。将 “Authentication Type” 保留为 “None”(默认)。确保选中 “Use controllers ...” 选项。
- 9) 确保未选中 “Enable Docker,”、“Configure for HTTPS” 和 “Enable Open API Support” 复选框,因为我们不会在此处使用任何这些功能。您也可以选择取消选中 “Use controllers(取消选中以使用最少的 API)” 复选框,因为我们将创建自己的控制器。
- 10) 单击创建。
这将在 Visual Studio 2022 中创建一个新的 ASP.NET Core 6 Web API 项目。我们将在本文的后续部分中使用该项目来说明 Dispose 的用法。
1. 创建一个实现 IDisposable 接口的类
我们现在将创建一个实现 IDisposable 接口的类,代码如下:
public class FileManager: IDisposable {
FileStream fileStream = new FileStream(@"C:\Test.txt",
FileMode.Append);
public async Task Write(string text) {
byte[] buffer = Encoding.Unicode.GetBytes(text);
int offset = 0;
try {
await fileStream.WriteAsync(buffer, offset,
buffer.Length);
}
catch {
//Write code here to handle exceptions.
}
}
public void Dispose() {
if (fileStream != null) {
fileStream.Dispose();
}
}
}
FileManager 类实现 IDisposable 接口并包含两个方法:Write 和 Dispose。前者用于将文本异步写入文件,后者用于通过调用 FileStream 类的 Dispose 方法从内存中删除 FileStream 实例。
下面,我们介绍在 ASP.NET Core 6 中处理 IDisposable 对象的四种方法。
2. 使用 “using” 语句处理 IDisposable 对象
处理 IDisposable 实例的最简单方法是使用“using”语句,它会自动调用实例上的 Dispose 方法。以下代码片段说明了这一点。
using(FileManager fileManager = new FileManager())
{
await fileManager.Write("This is a text");
}
3. 在请求结束时处理 IDisposable 对象
在 ASP.NET Core 或 ASP.NET Core MVC 应用程序中工作时,我们可能经常需要在 HTTP 请求结束时处理对象。
HttpResponse.RegisterForDispose 方法可用于以这种方式注册 IDisposable 对象以进行处理。它接受实现 IDisposable 接口的类的实例,并确保作为参数传递给它的 IDisposable 对象随每个请求自动处理。
以下代码演示了如何使用 HttpResponse.RegisterForDispose 方法在每个 HTTP 请求结束时注册 FileManager 类的实例。
public class DefaultController: ControllerBase {
readonly IDisposable _disposable;
public DefaultController() {
_disposable = new FileManager();
}
}
4. 使用内置的 IoC 容器处理 IDisposable 对象
另一种自动处理 IDisposable 对象的方法是使用 ASP.NET Core 中的内置 IoC(控制反转)容器。您可以利用 Transient、Scoped 或 Singleton 实例来创建服务并将它们添加到内置 IoC 容器中。
将 IDisposable 对象添加到 Startup 类的 ConfigureServices 方法中的 IoC 容器,以便这些对象随每个 HTTP 请求自动处理。
5. 使用 IHostApplicationLifetime 事件处理 IDependency 对象
ASP.NET Core 有一个名为 IHostApplicationLifetime 的接口,允许您在应用程序启动或关闭时运行自定义代码。您可以利用此接口的 Register 方法来注册事件。
Startup 类的 Configure 方法可以接受以下参数:
- IApplicationBuilder
- IHostingEnvironment
- ILoggerFactory
- IHostApplicationLifetime
以下代码演示了如何使用 IHostApplicationLifetime 接口注册对象以在应用程序关闭时进行处置。
public void Configure(IApplicationBuilder app, IHostApplicationLifetime hostApplicationLifetime) {
hostApplicationLifetime.ApplicationStopping.Register(OnShutdown);
}
private void OnShutdown() {
// 释放对象的代码
}
最后,ASP.NET Core 6 中默认不会创建 Startup.cs。我们需要手动创建一个,然后在 Program.cs 文件中编写以下代码以指定您将在其中使用的 Startup 类应用程序。
var builder = WebApplication.CreateBuilder(args);
builder.Host.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
using var app = builder.Build();
app.Run();
与 Finalize 不同,我们显式使用 Dispose 方法来释放非托管资源。您应该在实现它的任何对象上显式调用 Dispose 方法,以释放该对象可能持有其引用的任何非托管资源。
参考资料:
1. C#教程
2. 编程宝库
ASP.NET 使用 Dispose 释放资源的四种方法的更多相关文章
- asp.net后台注册js的四种方法
1. 用Response.Write方法 代码如下: Response.Write("<script type='text/javascript'>alert("kel ...
- 【AS3】Flash与后台数据交换四种方法整理
随着Flash Player 9的普及,AS3编程也越来越多了,所以这次重新整理AS3下几种与后台数据交换方法.1.URLLoader(URLStream)2.FlashRemoting3.XMLSo ...
- 两个变量交换的四种方法(Java)
对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...
- 织梦DedeCMS模板防盗的四种方法
织梦(DedeCMS)模板也是一种财富,不想自己辛辛苦苦做的模板被盗用,在互联网上出现一些和自己一模一样的网站,就需要做好模板防盗.本文是No牛收集整理自网络,不过网上的版本都没有提供 Nginx 3 ...
- 让一个图片在div中居中(四种方法)
第一种方法: <div class="title"> <div class="flag"></div> <div cl ...
- 运行jar应用程序引用其他jar包的四种方法
转载地址:http://www.iteye.com/topic/332580 大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个ja ...
- java中定时器的四种方法
package com.lid; import java.util.Calendar; import java.util.Date; import java.util.Timer; import ja ...
- Angular--页面间切换及传值的四种方法
1. 基于ui-router的页面跳转传参(1) 在AngularJS的app.js中用ui-router定义路由,比如现在有两个页面,一个页面(producers.html)放置了多个produce ...
- MYSQL获取自增ID的四种方法
MYSQL获取自增ID的四种方法 1. select max(id) from tablename 2.SELECT LAST_INSERT_ID() 函数 LAST_INSERT_ID 是与tabl ...
随机推荐
- 题解 「ZJOI2018」历史
题目传送门 Description 九条可怜是一个热爱阅读的女孩子. 这段时间,她看了一本非常有趣的小说,这本小说的架空世界引起了她的兴趣. 这个世界有 \(n\) 个城市,这 \(n\) 个城市被恰 ...
- jenkins容器内安装Python3之后使用pip3 install xxx失败,可以考虑换国内源
问题:pip3 install xxx失败 方案一:修改配置文件 首先在当前用户目录下建立文件夹.pip,然后在文件夹中创建pip.conf文件,再将源地址加进去即可. mkdir ~/.pipvim ...
- 2021.1.23--vj补题
B - B CodeForces - 879B n people are standing in a line to play table tennis. At first, the first tw ...
- 重庆邮电大学第十一届ACM程序设计竞赛-网络选拔赛 C题
1008: 偷袭 时间限制: 1.000 sec 内存限制: 128 MB 武林要以和为贵,张麻子不讲武德来偷袭马老师的亲传弟子. 马老师有n个亲传弟子,每个弟子有一个武力值a[i]. n个弟子中只有 ...
- [源码解析]PyTorch如何实现前向传播(2) --- 基础类(下)
[源码解析]PyTorch如何实现前向传播(2) --- 基础类(下) 目录 [源码解析]PyTorch如何实现前向传播(2) --- 基础类(下) 0x00 摘要 0x01 前文回顾 0x02 Te ...
- 【数据结构与算法Python版学习笔记】目录索引
引言 算法分析 基本数据结构 概览 栈 stack 队列 Queue 双端队列 Deque 列表 List,链表实现 递归(Recursion) 定义及应用:分形树.谢尔宾斯基三角.汉诺塔.迷宫 优化 ...
- Java:锁笔记
Java:锁笔记 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 1. Java 锁之公平锁和非公平锁 公平锁 是指多个线程按照申请锁的顺序来获取锁,类似于排队买 ...
- 2021北航敏捷软工Beta阶段评分与总结
概述 Beta 阶段评分,按照之前的规则,主要组成部分为: 博客部分,基于 Beta 阶段博客的评分(每篇正规博客 10 分,每篇 Scrum5 分,评定方式类比往年) 评审部分,基于 Beta 阶段 ...
- 是兄弟就来摸鱼 Scrum Meeting 博客汇总
是兄弟就来摸鱼 Scrum Meeting 博客汇总 一.Alpha阶段 第一次Scrum meeting 第二次Scrum meeting 第三次Scrum meeting 第四次Scrum mee ...
- 搬运1:关于对C语言中数组名取地址加减等操作的一点探究
对于数组名取地址强制转换的操作 偶然在晚上学了C语言指针后网页闲逛找题时,被一个数组名取地址搞糊涂了,在自己试验加探索后我稍微悟了一点东西. 代码如下: #include<stdio.h> ...