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 的用法。
2. 创立一个实现 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 对象的四种办法。
3. 应用 “using” 语句解决 IDisposable 对象
解决 IDisposable 实例的最简略办法是应用“using”语句,它会主动调用实例上的 Dispose 办法。以下代码片段阐明了这一点。
using(FileManager fileManager = new FileManager()){ await fileManager.Write("This is a text");}
4. 在申请完结时解决 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(); }}
5. 应用内置的 IoC 容器解决 IDisposable 对象
另一种主动解决 IDisposable 对象的办法是应用 ASP.NET Core 中的内置 IoC(管制反转)容器。您能够利用 Transient、Scoped 或 Singleton 实例来创立服务并将它们增加到内置 IoC 容器中。
将 IDisposable 对象增加到 Startup 类的 ConfigureServices 办法中的 IoC 容器,以便这些对象随每个 HTTP 申请主动解决。
6. 应用 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 办法,以开释该对象可能持有其援用的任何非托管资源。
参考资料:
- C#教程
- 编程宝库