2011-04-12 70 views
2

實現IDbConnectionIDbCommandIDataReader的數據庫訪問類都實現IDisposable,但很明顯,命令和讀者都依賴於連接上。我的問題是,我必須單獨Dispose()每個這些對象還是將處置Connection對象處置其他對象?如何在ADO.NET對象上調用Dispose?

也就是說,我能做到這一點,並保證我不會冒着留下任何非託管資源不被釋放:

using (IDbConnection conn = GetConnection()) 
{ 
     IDbCommand cmd = conn.CreateCommand(); 
     cmd.CommandText = " ..... "; 
     IDataReader rdr = cmd.ExecuteReader(); 
     while (rdr.Read()) 
     { 

     } 
} 

還是我必須這樣做,而不是:

using (IDbConnection conn = GetConnection()) 
{ 
    using (IDbCommand cmd = conn.CreateCommand()) 
    { 
     cmd.CommandText = " ..... "; 
     using (IDataReader rdr = cmd.ExecuteReader()) 
     { 
      while (rdr.Read()) 
      { 

      } 
     } 
    } 
} 

或者這個實現是依賴的,所以它可能會使用一個數據庫的提供者,但不適用於其他的?

回答

4

最好的策略是使用所有ADO.NET對象中的使用塊 - 句號。

稍微反映一下各種ADO.NET對象,表明如果不關閉/處置,事情或多或少會落在地板上。這樣做的效果將取決於你正在使用哪些提供程序 - 如果你正在使用下面的非託管句柄(ODBC,OleDb等),你可能會泄漏內存,因爲我什麼也沒有看到在終結者的方式。如果它是一個全能管理的提供者(例如SqlClient),它最終會得到清理,但取決於你所持有的對象,最終可能會在數據庫服務器上使用比您想要的更長的資源。

1

您應該單獨處理它們,或者也可以使用提供的解決方案here

1

單獨處置它們。 Reader和Command對象完全有可能在其處理例程中執行更多的操作,而不僅僅是破壞連接(現在或將來的ADO.NET版本)。所以爲了(a)要明確,並且(b)要安全,你應該單獨處理它們。

它們實現IDisposable的事實表明,當你完成對象時,你應該總是運行Dispose例程,所以最好不要嘗試和猜測接口,它不會給你帶來任何好處,並且你可能最終會泄漏內存和句柄。

雖然在嵌套using語句時可以使代碼看起來更清晰,但您仍可以執行某些操作。例如:

(using SqlConnection conn = new SqlConnection()) 
(using SqlCommand comm = new SqlCommand()) 
{ 
    //Do stuff 
} 

這看起來比嵌套牙套更整潔(在我看來)。

0

您應該單獨處置它們。即使處置IDbConnection會將所有內容處理掉(我不知道它是否真的存在,我也不關心,因爲後面的原因),您應該按將來時間進行編程。明天有人會編輯該代碼並在同一連接上發出一個新命令,然後它會問他爲什麼會收到連接仍在使用中的錯誤(因爲IDataReader沒有處理)。

0

使用語句的主要優點是資源釋放管理。通常,.NET Framework垃圾收集器控制資源分配和釋放。通過使用聲明,我們可以控制它。因此,using語句實現了一個包含公共Dispose()方法的IDisposible接口。

此外,您也可以始終手動調用Dispose()方法以釋放內存中的資源或對象。

希望這有助於。

相關問題