在不再需要时处置 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
        }
    }
}

请注意,此示例不是线程安全的