- IDisposable
- 因補償 GC 不會馬上回收資源,使資源延後被歸還的時間,可在類別中實作 IDisposable 介面
- Code
///
/// IDisposable
/// 1. 需實作 IDisposable 介面
/// 2. 加入 IDisposable 方法供外部程式呼叫: 馬上釋放資源
/// 3. 因 IDisposable 介面定意了一個方法 Dispose()
/// 一般程式可呼叫此方法,要求物件馬上釋放其中使用到的資源
/// 如此不需等到 GC 服務啟動才能釋放
///
public class UserInfo : IDisposable
{
public string sUserName { get; set; }
///
/// 建構函式
/// 1. 每個物件只會執行一次
/// 2. 只透過 new 關鍵字引發執行
/// 3. 無須指定傳回值及型別
/// 4. 建立物件類別時沒有宣告"建構函式",編譯程式時會自動加入預設"建構函式"
/// 5. "建構函式"可以使用多型
/// 6. "建構函式"使用 this 關鍵字轉向呼叫,將會把值帶入 "建構函式 I"
///
public UserInfo():this("Lyndon")
{
}
///
/// 建構函式 I (多型)
///
public UserInfo(string username)
{
sUserName = username;
}
///
/// 解構函式
/// 1. 釋放所有使用到的外部資源
/// 2. 外部程式無法直接呼叫"解構函式"
/// 3. "解構函式"不一定會馬上執行
/// 4. "解構函式"不能被繼承或多載
/// 5. 如有撰寫"解構函式",將會在 CLR 有排程
/// 6. 通常不撰寫"解構函式", CLR 會有排程(第5點),因此會影響效能
///
~UserInfo()
{
Dispose(false);
}
///
/// 釋放資源
///
private bool bDisposed = false;
///
/// 釋放資源 (程式設計師呼叫)
///
public void Dispose()
{
Dispose(true);
// GC.SuppressFinalize(this) 目的
// 通知 GC,物件已完成釋放資源動作,GC 不需要再呼叫此物件 Finalize() 方法
// PS: 因為此範例有宣告"解構函式",如果不宣告 GC.SuppressFinalize(this) 將會觸發"解構函式",使 GC 觸發兩次
GC.SuppressFinalize(this);
}
///
/// 釋放資源 (系統呼叫)
///
protected virtual void Dispose(bool IsDisposing)
{
if (bDisposed)
{
return;
}
if (IsDisposing)
{
// 補充:
// 這裡釋放具有實做 IDisposable 的物件(資源關閉或是 Dispose 等..)
// ex: DataSet DS = new DataSet();
// 可在這邊 使用 DS.Dispose();
// 或是 DS = null;
// 或是釋放 自訂的物件。
// 因為沒有這類的物件,留下這段 code
// 若繼承這個類別,可覆寫這個函式。
}
bDisposed = true;
}
}
using
- using 區塊,使用它可確保資源在離開此區塊時馬上被釋放
- 如果程式中有使用到如下列的資源,請務必使用 using
- Code
// using
// 1. 預設資源回收動作為 GC 負責
// 2. 物件透過 using 宣告,確保離開 using 區域時馬上釋放物件
// 3. 物件必需實作 IDisposable 介面
using(UserInfo ui = new UserInfo())
{
// UserInfo member ...
}
沒有留言:
張貼留言