在不再需要時處置 Singleton 例項

大多數示例都顯示例項化並持有 LazySingleton 物件,直到擁有的應用程式終止,即使應用程式不再需要該物件。對此的解決方案是實現 IDisposable 並將物件例項設定為 null,如下所示:

public class LazySingleton : IDisposable
{
    private static volatile Lazy<LazySingleton> _instance;
    private static volatile int _instanceCount = 0;
    private bool _alreadyDisposed = false;

public static LazySingleton Instance
{
    get
    {
        if (_instance == null)
            _instance = new Lazy<LazySingleton>(() => new LazySingleton());
        _instanceCount++;
        return _instance.Value;
    }
}

private LazySingleton() { }

// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{ 
    if (--_instanceCount == 0) // No more references to this object.
    {       
       Dispose(true);
       GC.SuppressFinalize(this);           
    }
}

// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
    if (_alreadyDisposed) return; 
  
    if (disposing) 
    {
        _instance = null; // Allow GC to dispose of this instance.
        // Free any other managed objects here.
    }
  
    // Free any unmanaged objects here.
    _alreadyDisposed = true;
}

上述程式碼在應用程式終止之前處理例項,但僅限於消費者在每次使用後在物件上呼叫 Dispose()。由於無法保證會發生這種情況或強迫它,因此也無法保證例項將被處置。但如果在內部使用此類,則更容易確保在每次使用後呼叫 Dispose() 方法。一個例子如下:

public class Program
{
    public static void Main()
    {
        using (var instance = LazySingleton.Instance)
        {
            // Do work with instance
        }
    }
}

請注意,此示例不是執行緒安全的