簡體   English   中英

我是否需要明確地關閉和處置 SQLConnection?

[英]Do I need to close and dispose the SQLConnection explicitly?

SqlDataReader rdr = null;
con = new SqlConnection(objUtilityDAL.ConnectionString);
using (SqlCommand cmd = con.CreateCommand())
{
    try
    {
        if (con.State != ConnectionState.Open)
            con.Open();
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(Parameter);
        cmd.CommandText = _query;
        rdr = cmd.ExecuteReader();
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

在上面的代碼中,sqlconnection 在托管代碼中打開。 因此,連接對象會在結束 USING 范圍時自動處理嗎?

您必須關心SqlConnection的處理,因為它是一個一次性對象。 你可以試試這個:

using(var sqlConnection = new SqlConnection(objUtilityDAL.ConnectionString))
{
    using (SqlCommand cmd = con.CreateCommand())
    {
        // the rest of your code - just replace con with sqlConnection
    }
}

我建議您用局部變量替換con - 如果還沒有(從您發布的代碼中看不出)。 為此無需使用類字段。 只需創建一個局部變量,跟蹤它會更清楚。

您應該Dispose手動創建的每個臨時IDisposable實例,即將它們包裝成using

   // Connecton is IDisposable; we create it 
   //   1. manually - new ...
   //   2. for temporary usage (just for the query)
   using (SqlConnection con = new SqlConnection(objUtilityDAL.ConnectionString)) {
     // Check is redundant here: new instance will be closed 
     con.Open();

     // Command is IDisposable
     using (SqlCommand cmd = con.CreateCommand()) {
       cmd.CommandType = CommandType.StoredProcedure;
       cmd.Parameters.Add(Parameter);
       cmd.CommandText = _query;

       // Finally, Reader - yes - is IDisposable 
       using (SqlDataReader rdr = cmd.ExecuteReader()) {
         // while (rdr.Read()) {...}
       }
     }   
   }

請注意

   try {
     ...
   }
   catch (Exception ex) {
     throw ex;
  } 

至少是多余的它只是重新拋出異常,而失去堆棧跟蹤),這就是為什么可以被退學

一般來說:

在 .Net 框架中,不會自動處理任何內容。 否則我們就不需要IDisposable接口。 垃圾收集器只能處理托管資源,因此每個非托管資源都必須在 dispose 方法中的代碼中處理。

因此,作為一項規則,每個實現IDisposable類的每個實例都必須通過調用它的Dispose方法顯式地或using語句隱式地進行Dispose

作為最佳實踐,您應該努力使用任何實現IDisposable接口的東西作為 using 語句中的局部變量:

using(var whatever = new SomeIDisposableImplementation())
{
    // use the whatever variable here
}

using語句是語法糖。 編譯器將其翻譯成這樣:

var whatever = new SomeIDisposableImplementation();
try
{
    // use the whatever variable here
}
finally
{
    ((IDisposable)whatever).Dispose();
}

由於無論try塊中發生什么, finally塊都保證運行,因此您的IDisposable實例可以保證被正確處理。

特別是使用SqlConnection為了將連接對象返回到連接池,你必須在完成后處理它(Dispose 方法也會關閉連接,所以你不需要顯式關閉它) - 所以正確使用SqlConnection始終作為using語句中的局部變量:

using(var con = new SqlConnection(connectionString))
{
    // do stuff with con here
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM