1. 程式人生 > 其它 >ASP.NET 使用 Dispose 釋放資源的四種方法

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. 程式設計寶庫