許多開發者認為 Close() 內部會調用 Dispose(),兩者無本質區別。實則不然——視具體類別實現而定,盲目互換可能導致資源洩漏或效能問題。
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); // 關鍵:抑制終結器,避免延遲回收
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
lock(this)
{
// 從容器移除、觸發 Disposed 事件等
}
}
}
override public void Close()
{
// 複雜的連接關閉邏輯:統計、鎖定、關閉內部連接、處理連接池
// ...
// 注意:並未調用 Dispose(),僅在 finally 中處理 SqlDebugContext
SqlDebugContext sdc = _sdc;
_sdc = null;
if (sdc != null) sdc.Dispose(); // 僅釋放調試上下文,非 SqlConnection 本身
}
| 特性 | Close() | Dispose() |
|---|---|---|
| 連接狀態 | 關閉連接,歸還連接池(Pooling=true) | 釋放所有資源,連接不可再使用 |
| 可重新開啟 | 是,可再次呼叫 Open() | 否,物件已失效 |
| GC 壓力 | 未呼叫 SuppressFinalize,物件會進入最終化佇列,延遲回收 | 呼叫 SuppressFinalize,立即標記可回收 |
Close()(或 using 區塊自動處理)Dispose() 或 using (var conn = new SqlConnection()) { ... }// Stream.Close()
public virtual void Close()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Stream.Dispose()
public void Dispose()
{
Close(); // 直接委派給 Close()
}
標準 Dispose 模式實現,Close() 與 Dispose() 互相調用,功能完全一致。
Close() 內呼叫 Dispose(true) + GC.SuppressFinalize(this)Close() 與 Dispose() 的關係取決於具體類別實現。SqlConnection 兩者語義不同,FileStream 則等效。養成「用 using 管理資源生命週期」的習慣,比糾結呼叫哪個方法更可靠、更符合 .NET 設計哲學。