簡體   English   中英

使用IDisposable時放置try / catch的位置

[英]Where to put try/catch when using IDisposable

我只是建議在try放置一個完整的using塊,否則using scope將阻止異常被捕獲。 但是,如果拋出異常,是否會阻止using正確處理其資源? 如果我有下面的代碼,我應該把try塊放在哪里?

using (connSQL = new SqlConnection(strConn)) 
{
    connSQL.Open();
    using (SqlCommand commSQL = new SqlCommand(strPreparedStatement, connSQL)) 
    {
        if (sqlParameters != null)
        {
            for (int i = sqlParameters.GetLowerBound(0); i <= sqlParameters.GetUpperBound(0); i++)
            {
                commSQL.Parameters.Add(sqlParameters[i]);
            }
        }
        drSQL = commSQL.ExecuteReader();
        dtReturn.Load(drSQL);

        commSQL.Parameters.Clear();
    }
}

在此應用程序中,確保與數據庫的連接不會因異常而開始累積更為重要。

using聲明將已阻止連接積聚-它的東西清除側對你來說,通過有效地作為一個try / finally與呼叫阻止對Disposefinally塊。 如果你想要一個try / catch塊,你可以把它放在里面或外面 - 但是你確定它不應該處於更高的水平嗎? 您實際上期望如何處理異常?

順便說一句,目前還不清楚為什么要在命令即將被處理時清除命令中的參數...

我鼓勵你也在using語句中聲明變量,這樣你最終不會試圖在塊之外讀取它們:

using (SqlConnection connSQL = new SqlConnection(strConn)) {

通常,您希望盡可能縮小范圍。 哦,你的SqlDataReader應該在using語句中。 無論如何,當你關閉連接和命令時,它可能無關緊要,但我會把它作為一個原則點 - 它實現IDisposable ,所以你應該處理它。

哦,你在sqlParameters上迭代的方式目前相當長。 foreach使它變得更簡單,即使它沒有for (int i = 0; i < sqlParameters.Length; i++)除非我有理由相信它不是一個“簡單”的數組。

所以,我的等效代碼看起來像這樣:

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    using (SqlCommand command = new SqlCommand(strPreparedStatement, connection))
    {
        if (sqlParameters != null)
        {
            // If sqlParameter is an array, you can just use
            // command.Parameters.AddRange(sqlParameters) instead
            foreach (SqlParameter parameter in sqlParameters)
            {
                command.Parameters.Add(parameter);
            }
        }
        using (SqlDataReader reader = command.ExecuteReader())
        {
            DataTable table = new DataTable();
            // Perform any extra initialization here
            table.Load(reader);
            return table;
        }
    }
}

您需要將數據讀取器包裝在using語句中,因為它是一次性資源:

using (var connSQL = new SqlConnection(strConn)) 
using (var commSQL = connSQL.CreateCommand()) 
{
    connSQL.Open();
    commSQL.CommandText = strPreparedStatement;
    if (sqlParameters != null)
    {
        for (int i = sqlParameters.GetLowerBound(0); i <= sqlParameters.GetUpperBound(0); i++)
        {
            commSQL.Parameters.Add(sqlParameters[i]);
        }
    }
    using (var drSQL = commSQL.ExecuteReader())
    {
        dtReturn.Load(drSQL);
    }
}

我還將連接,命令和數據讀取器對象本地定義到此塊作用域中。

try/finally語句而言,不再需要它,因為using語句確保即使在異常情況下也會調用Dispose方法。 這種用於sql連接和命令的方法可確保正確釋放它們。

沒有必要把try catch因為隱式using它,實際上它最后使用try並確定它會處理對象。

這是MSDN使用Sample關於try catch和使用:

{
  Font font1 = new Font("Arial", 10.0f);
  try
  {
    byte charset = font1.GdiCharSet;
  }
  finally
  {
    if (font1 != null)
      ((IDisposable)font1).Dispose();
  }
}

等於:

using (Font font3 = new Font("Arial", 10.0f),
            font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}

暫無
暫無

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

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