2009-07-21 57 views
5

我有下面的代碼來查詢存儲過程中的記錄,但是我擔心我可能不會處理我需要或正在處理的對象在不久之後將被垃圾收集器清除的情況。c#sql要處置什麼

我是否需要處理SqlDataReader,因爲它位於try catch塊內?

我是否需要運行cmd.Dispose和cmd.Connection.Close,或者是否推斷另一個?

無論如何垃圾收集器最終會處理所有這些對象(可能不夠及時)或者由於使用非託管代碼而使這些對象暗含需要處置?

public void GetData(string studentID) 
    { 
     SqlCommand cmd = new SqlCommand("sp_stored_proc", 
       new SqlConnection(Settings.Default.connectionString)) 
       { CommandType = CommandType.StoredProcedure }; 
     try 
     { 
      cmd.Connection.Open(); 
      cmd.Parameters.AddWithValue("@student_id", studentID); 
      SqlDataReader dr = cmd.ExecuteReader(); 

     //do something with the data 

      if (dr != null) 
       dr.Dispose(); 
     } 
     catch 
     { 
      //error handling 
     } 
     finally 
     { 
      if (cmd != null) 
      { 
       cmd.Dispose(); 
       cmd.Connection.Close(); 
      } 

     } 

    } 

回答

16

你應該處理的數據讀取器和命令。如果您處理命令,則無需單獨關閉連接。理論上,應該做到既使用using塊:

using (SqlCommand cmd = new...) 
{ 
    // do stuff 
    using (SqlDataReader dr = cmd.ExecuteReader()) 
    { 
     // do stuff 
    } 
} 

如果你需要異常處理做單獨的內部或使用塊周圍 - 不需要在最後的Dispose電話雖與using

3

我需要處置SqlDataReader的 既然是嘗試捕捉 塊內?

- 是的,因爲在try catch裏面不會調用dispose方法。

我是否需要運行cmd.Dispose和cmd.Connection.Close或者是否推斷另一個?

- 是的,你需要同時運行。調用Cmd.dispose不會關閉連接。

dispose方法是爲了讓程序員用來清理不是由垃圾收集器直接管理的資源,或是在程序完成後使用它們釋放空間而需要清除的資源。從技術上講,可以設置程序,以便GC能夠處理它的處置,但這是我不會做的假設,尤其是因爲編寫該類的程序員爲您公開了處理方法。將命令放在using語句中可能是最簡單的路由,因爲您知道當代碼離開聲明空間時它將被丟棄。

using (var connection = new Connection()) 
{ 
    using (var cmd = new Command()) 
    { 



    } 
} 
+0

「不,cmd.dispose將關閉連接」 - 我認爲這是不正確的;據我所知,在命令中調用Dispose與其連接無關。 – 2009-07-21 12:05:52

+0

@Kevin:你鏈接到的狀態,調用一個*連接對象*上的Dispose會調用關閉該同一個對象。 「命令」一詞不會出現在頁面上。 – 2009-07-21 12:15:34

+0

我誤讀了帖子時,我再次檢查。你是對的。 – kemiller2002 2009-07-21 12:16:55

2

就個人而言,如果有東西有處置方法,那麼值得使用它,因爲它們將防止潛在的內存泄漏。

3

如果使用這樣的事情:

public void GetData(string studentID) 
{ 
    using (SqlConnection connection = new SqlConnection(Settings.Default.connectionString)) 
    { 
     connection.Open(); 

     using (SqlCommand command = connection.CreateCommand()) 
     { 
      command.CommandType = CommandType.StoredProcedure; 
      command.CommandText = "sp_stored_proc"; 
      command.Parameters.AddWithValue("@student_id", studentID); 

      using (SqlDataReader dataReader = command.ExecuteReader()) 
      { 
       // do something with the data 
      } 
     } 
    } 
} 

您一次性的對象,那麼一切都將得到正確處置。在SqlConnection,SqlCommand和SqlDataReader對象上調用Dispose()(這是使用塊在退出時的行爲)會正確關閉它們。

此外,這種方法可以將所有變量限定在使用位置。

這種方法的缺點是,如果您需要使用try/catch進行錯誤處理,則必須將其包裝在整個方法體中,或者使用其中的幾個來處理與讀取錯誤等不同的連接錯誤。 ..

1

長話短說;如果它實施IDisposable,則應該致電Dispose

即使您使用反射來弄清楚,Dispose在一個物體上的其他對象調用Dispose,我還是會建議呼籲兩國Dispose,因爲這是內部實現細節,可能在未來的版本改變,所以你不應該依賴那總是真實的。

所以,Dispose什麼是IDisposable

-4

你應該首先通過Connection.Open()打開Connection。 然後使用方法,如SqlDataReader的閱讀 畢竟,密切SqlDataReader的先,然後關閉連接

您可以使用「使用」處置它的關鍵字,但它不是其實是一個好主意

關鍵字「使用」是自動處理對象。 換言之,該對象應該實現處理方法

相關問題