在不再需要時處置 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
}
}
}
請注意,此示例不是執行緒安全的。