關於 SqlConnection 的 Close() 與 Dispose(),以及 using 語句的選擇,網上眾說紛紛。本文結合微軟 ADO.NET 團隊官方說明與源碼分析,給出明確結論。
微軟 ADO.NET 團隊項目經理 Pablo Castro 明確指出:
對於微軟提供的提供程序,
Close()和Dispose()基本做同一件事。唯一區別是Dispose()會清空連接字符串(設置為 null)。調用其中一個即可。
SqlConnection con = new SqlConnection(connStr);
con.Open();
con.Close();
con.Open(); // 成功:連接返回池中,狀態重置
con.Dispose();
con.Open(); // 拋出 InvalidOperationException:ConnectionString 未初始化
// 若 Dispose 後重新賦值 ConnectionString,則可正常 Open
con.ConnectionString = connStr;
con.Open(); // 成功
查看 SqlConnection 源碼(.NET Framework 參考源碼):
protected override void Dispose(bool disposing)
{
if (disposing)
{
this._userConnectionOptions = null; // 清空連接字符串
this._poolGroup = null;
this.Close(); // 內部調用 Close
}
this.DisposeMe(disposing);
base.Dispose(disposing);
}
結論:Dispose() 包含 Close() 的所有行為,並額外清理連接字符串相關字段。兩者均不銷毀對象,只是將連接歸還連接池。對象銷毀由連接池根據閒置超時(Connection Lifetime)管理。
using 編譯為 try { ... } finally { obj.Dispose(); },不捕獲異常,僅保證釋放。try/finally 易出錯(有人寫 Close()、有人寫 Dispose()),且代碼冗長。using。Dispose 後重新初始化連接字符串的納秒級開銷,可忽略不計。// 標準模式:簡潔、安全、符合框架慣例
using (var conn = new SqlConnection(connStr))
{
conn.Open();
// 執行命令...
} // 自動 Dispose -> Close -> 歸還連接池
大膽使用 using,它是處理 IDisposable 資源的標準、推薦方式。