當託管對象不再使用時,記憶體回收行程會自動釋放分配給該對象的記憶體,不過進行記憶體回收的時間不可預知。而且,記憶體回收行程對視窗控制代碼、開啟的檔案和流等非託管資源一無所知。
當不再需要某對象時,對象的使用者可以通過調用 Dispose 方法(記憶體回收行程釋放資源時也是調用該方法)來顯式的釋放託管和非託管資源。
public class BaseDisposable : IDisposable
{
~BaseDisposable()
{
//記憶體回收行程將調用該方法,因此參數需要為false。
Dispose(false);
}
/// <summary>
/// 是否已經調用了 Dispose(bool disposing)方法。
/// 應該定義成 private 的,這樣可以使基類和子類互不影響。
/// </summary>
private bool disposed = false;
/// <summary>
/// 所有回收工作都由該方法完成。
/// 子類應重寫(override)該方法。
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
// 避免重複調用 Dispose 。
if (!disposed) return;
// 適應多線程環境,避免產生線程錯誤。
lock (this)
{
if (disposing)
{
// ------------------------------------------------
// 在此處寫釋放託管資源的代碼
// (1) 有 Dispose() 方法的,調用其 Dispose() 方法。
// (2) 沒有 Dispose() 方法的,將其設為 null。
// 例如:
// xxDataTable.Dispose();
// xxDataAdapter.Dispose();
// xxString = null;
// ------------------------------------------------
}
// ------------------------------------------------
// 在此處寫釋放非託管資源
// 例如:
// 檔案控制代碼等
// ------------------------------------------------
disposed = true;
}
}
/// <summary>
/// 該方法由程式調用,在調用該方法之後對象將被終結。
/// 該方法定義在IDisposable介面中。
/// </summary>
public void Dispose()
{
//因為是由程式調用該方法的,因此參數為true。
Dispose(true);
//因為我們不希望記憶體回收行程再次終結對象,因此需要從終結列表中去除該對象。
GC.SuppressFinalize(this);
}
/// <summary>
/// 調用 Dispose() 方法,回收資源。
/// </summary>
public void Close()
{
Dispose();
}
}