首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

Effective C# 原則 18:實作標準 Dispose 模式

     編輯:關於C#

佔用非受控資源(檔案控制代碼、資料庫連線、GDI+ 物件、COM 物件等)的型別,必須正確釋放資源。.NET 提供標準 Dispose 模式,配合 IDisposable 介面與完成項,確保資源在使用者呼叫 Dispose() 時立即釋放,若使用者忘記,則由完成項在垃圾回收時被動釋放。

標準 Dispose 模式三要素

  1. 實作 IDisposable:提供 Dispose() 釋放受控與非受控資源。
  2. 提供完成項:~ClassName() 呼叫 Dispose(false),作為最後防線。
  3. 受保護虛擬 Dispose(bool):核心清理邏輯,衍生類可覆寫並呼叫基類實作。

基類實作範本

public class MyResourceHog : IDisposable
{
    private bool _alreadyDisposed = false;

    ~MyResourceHog() => Dispose(false);

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool isDisposing)
    {
        if (_alreadyDisposed) return;
        if (isDisposing)
        {
            // 釋放受控資源
        }
        // 釋放非受控資源
        _alreadyDisposed = true;
    }
}

衍生類實作範本

public class DerivedResourceHog : MyResourceHog
{
    private bool _disposed = false;

    protected override void Dispose(bool isDisposing)
    {
        if (_disposed) return;
        if (isDisposing)
        {
            // 釋放衍生類受控資源
        }
        // 釋放衍生類非受控資源
        base.Dispose(isDisposing);
        _disposed = true;
    }
}

關鍵規則

  • 只釋放資源:Dispose 與完成項絕不可執行除資源釋放外的任何邏輯(如讓物件復活),否則會導致嚴重 Bug。
  • 多次呼叫安全:Dispose 與完成項必須支援重複呼叫不拋出例外。
  • 避免不必要的完成項:僅在型別直接持有非受控資源或包含 IDisposable 成員時才加入完成項;否則僅實作 IDisposable 即可,避免影響衍生類實作標準模式。

為什麼這樣設計?

完成項執行於專用執行緒,物件需多經歷至少一次 GC 週期才能被回收,造成效能負擔。GC.SuppressFinalize(this) 讓主動釋放的物件跳過完成項佇列,提升效能。標準模式同時解決:基類與衍生類各自追蹤釋放狀態、受控/非受控資源分離清理、版本演進時的相容性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved