[英]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
與呼叫阻止對Dispose
的finally
塊。 如果你還想要一個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.