2011-03-08 26 views
1

我在VS 2010中有一堆類似於我的DAL的方法。當我運行「新」代碼分析選項時,我得到消息 - 警告CA2000對象'comm '不是沿着所有異常路徑處理的。在所有對它的引用超出範圍之前,調用System.IDisposable.Dispose對象'comm'。CA2000對象'comm'不是沿着所有異常路徑設置的

我知道我可以爲SQLCommand使用另一個using語句,但是如果喜歡像Try/Finally塊一樣使用它。我的理解是Finally塊最後執行並進行清理。有人在我的處置電話中看到有什麼不對嗎?

public List<Product> GetAllProducts() 
    { 

     List<Product> prodList = new List<Product>(); 
     using (SqlConnection connection = new SqlConnection(GetConnection())) 
     { 
      SqlCommand comm = new SqlCommand("GetAllProducts", connection); 
      connection.Open(); 
      comm.CommandType = CommandType.StoredProcedure; 
      SqlDataReader dr = comm.ExecuteReader(); 
      try 
      { 
       while (dr.Read()) 
       { 
        Product obj = new Product(); 
        obj.ProductID = Convert.ToInt32(dr["ProductID"].ToString()); 
        obj.Product = dr["Product"].ToString(); 
        //etc....                  

        prodList.Add(obj); 
       } 
      } 
      finally 
      { 
       comm.Dispose(); 
       dr.Close(); 
      } 
     } 

     return prodList; 
    } 

} 

回答

1

如果這三個語句中的任何一個拋出異常,則不會拋棄comm

 connection.Open(); 
     comm.CommandType = CommandType.StoredProcedure; 
     SqlDataReader dr = comm.ExecuteReader(); 

您的嘗試塊也需要包含這些語句。

+0

如果我這樣做,那麼我必須從最終塊中刪除dr.cose(),因爲我得到一個錯誤消息「dr在當前上下文中不存在」。這有意義嗎?我只是想,如果發生錯誤,我會希望dr.close特別在finally塊中。 – chris 2011-03-08 22:08:56

+0

您需要處理兩個不同的對象,並且這些對象分配在不同的行上。這意味着您需要使用兩個try/finally塊,或者您需要將其中的一個初始化爲null,並在調用dispose之前確保它不爲null。 – 2011-03-08 22:13:10

+0

我不認爲我見過2嘗試最後的塊,並沒有聽起來對我正確。我剛剛實現了使用(SqlCommand comm = new SqlCommand(「GetAllProducts」,connection)),並且代碼分析仍然說 「在對象'comm'上調用System.IDisposable.Dispose之前,所有引用都超出了範圍。和 在所有對它的引用超出範圍之前,調用System.IDisposable.Dispose對象'connection'。 – chris 2011-03-08 22:26:20

0
 List<Measure_Type> MeasureList = new List<Measure_Type>(); 
     SqlConnection conn = null;    

     SqlDataReader rdr = null; 
     SqlCommand cmd = null; 
     try 
     { 
      conn = new SqlConnection(); 
      conn.ConnectionString = System.Configuration.ConfigurationManager.AppSettings["Conn"]; 
      conn.Open(); 
      cmd = new SqlCommand("SELECT Measure_ID, Mea_Name FROM MeasureTable WHERE IsActive=1", conn); 

      rdr = cmd.ExecuteReader(); 
      if (rdr.HasRows == true) 
      { 
       while (rdr.Read()) 
       { 
        MeasureTypeList.Add(new Measure_Type { MeasureTypeID = Convert.ToInt32(rdr[0]), MeasureTypeName = rdr[1].ToString() }); 
       } 
      } 
     } 

     catch (Exception ex) 
     { 
      ExceptionPolicy.HandleException(ex, "Log"); 
     } 
     finally 
     { 
      cmd.Dispose(); 
      // close the reader 
      if (rdr != null) { rdr.Close(); } 
      // Close the connection 
      if (conn != null) { conn.Dispose(); } 
     } 
     return MeasureTypeList; 

創建conn = new SqlConnection();裏面的try塊然後打開它來解決這個bug。

1

在命令和dataReader周圍放置一個使用塊,以便它們始終處理。

public List<Product> GetAllProducts() 
{ 
    List<Product> prodList = new List<Product>(); 
    using (SqlConnection connection = new SqlConnection(GetConnection())) 
    { 
     using (SqlCommand comm = new SqlCommand("GetAllProducts", connection)) 
     { 
      connection.Open(); 
      comm.CommandType = CommandType.StoredProcedure; 
      using (SqlDataReader dr = comm.ExecuteReader()) 
      { 
       try 
       { 
        while (dr.Read()) 
        { 
         Product obj = new Product(); 
         obj.ProductID = Convert.ToInt32(dr["ProductID"].ToString()); 
         obj.Product = dr["Product"].ToString(); 
         //etc....                  

         prodList.Add(obj); 
        } 
       } 
      } 
     } 
    } 

    return prodList; 
}