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 释放资源的四种方法的更多相关文章

  1. asp.net后台注册js的四种方法

    1. 用Response.Write方法 代码如下: Response.Write("<script type='text/javascript'>alert("kel ...

  2. 【AS3】Flash与后台数据交换四种方法整理

    随着Flash Player 9的普及,AS3编程也越来越多了,所以这次重新整理AS3下几种与后台数据交换方法.1.URLLoader(URLStream)2.FlashRemoting3.XMLSo ...

  3. 两个变量交换的四种方法(Java)

    对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...

  4. 织梦DedeCMS模板防盗的四种方法

    织梦(DedeCMS)模板也是一种财富,不想自己辛辛苦苦做的模板被盗用,在互联网上出现一些和自己一模一样的网站,就需要做好模板防盗.本文是No牛收集整理自网络,不过网上的版本都没有提供 Nginx 3 ...

  5. 让一个图片在div中居中(四种方法)

    第一种方法: <div class="title"> <div class="flag"></div> <div cl ...

  6. 运行jar应用程序引用其他jar包的四种方法

    转载地址:http://www.iteye.com/topic/332580 大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个ja ...

  7. java中定时器的四种方法

    package com.lid; import java.util.Calendar; import java.util.Date; import java.util.Timer; import ja ...

  8. Angular--页面间切换及传值的四种方法

    1. 基于ui-router的页面跳转传参(1) 在AngularJS的app.js中用ui-router定义路由,比如现在有两个页面,一个页面(producers.html)放置了多个produce ...

  9. MYSQL获取自增ID的四种方法

    MYSQL获取自增ID的四种方法 1. select max(id) from tablename 2.SELECT LAST_INSERT_ID() 函数 LAST_INSERT_ID 是与tabl ...

随机推荐

  1. MySQL的详细讲解

    目录 Mysql的架构与历史 MySQL的逻辑架构 更新中---- Mysql的架构与历史 MySQL的逻辑架构 第二层的架构是所有的跨引擎的功能实现的地方,例如:存储,触发器,视图等. 第三层半酣了 ...

  2. 一个简单的单例模式Demo

    /** * @author :nx014924 * @date :Created in 5/30/2021 1:09 PM * @description: * @modified By: * @ver ...

  3. 【UE4 C++】Tick的三种方式、异步蓝图节点

    Tick的三种方式 包括 默认 Tick (Actor.Component.UMG) TimerManager 定时器 FTickableGameObject 可以写原生 Object 也可以继承UO ...

  4. Python绘制Excel图表

    今天讲解下如何使用Python绘制各种Excel图表,下面我们以绘制饼状图.柱状图.水平图.气泡图.2D面积图.3D面积图为例来说明. import openpyxlfrom openpyxl imp ...

  5. WPF 排版基础

    一.WPF 排版基础 WPF使用控制面板来进行排版,控制面板实际上是一种可以放入WPF界面元素的容器.当用户把界面元素放入控制面板后,WPF会自动把这些界面元素放在它认为合适的地方.WPF开发人员需要 ...

  6. UML图 | 时序图(顺序、序列图)绘制

    上一次写过一篇 UML | 类图 相关的文章,平时规范开发会用的上,或者是写什么文档,就还是需要画图,就像毕业设计就是如此.希望能够帮助到大家. 注:本文中所用画图软件为 Microsoft Visi ...

  7. JVM:体系结构

    JVM:体系结构 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 概览 Java GC 主要回收的是 方法区 和 堆 中的内容 类加载器 类加载器是什么 双亲委派 ...

  8. 浅谈如何爆踩TLEcoders

    对付一些速度比老奶奶都慢的评测姬, 除了超级小的常数,往往还不得不使用一些不算办法的办法 比如说这个让人无语的$ACcoders$的评测姬, 当我们感到代码已经无法再卡常的时候,对人生已经近乎绝望的时 ...

  9. 2021.8.17考试总结[NOIP42]

    $\huge{取模不能比大小!}$ $\huge{取模不能比大小!}$ $\huge{取模不能比大小!}$ 有了打地鼠的前车之鉴,我深信树规板子是可以出现在联赛题里的. 所以T1十分钟码完直接溜了,后 ...

  10. Python之@property详解及底层实现介绍

    转自:https://blog.csdn.net/weixin_42681866/article/details/83376484 前文 Python内置有三大装饰器:@staticmethod(静态 ...