在我制作优秀代码的目标中,我使用“运行代码分析”在Visual Studio 2010中验证了我的项目。在下面的函数中,我得到以下警告,我不明白,因为唯一可以生成异常的行是 sqlC.ExecuteNonQuery(),只有 异常类型“ 的SQLException ”。
CA2000:Microsoft.Reliability:在方法'Company.log(string,string,DateTime,DateTime,string,bool)'中,对象'sqlC'不会沿所有异常路径放置。在对对象'sqlC'的所有引用超出范围之前调用System.IDisposable.Dispose。
为什么分析会抱怨?非常感谢任何帮助!
private void log(string type, string descr, DateTime start, DateTime end, string msg, bool success)
{
SqlCommand sqlC = new SqlCommand();
sqlC.CommandType = CommandType.Text;
sqlC.Connection = sc;
sqlC.CommandText = "INSERT INTO [cap_jobHistoryDetails] (...) VALUES(...)";
sqlC.Parameters.AddWithValue("@jobID", _job_id.ToString("d", CultureInfo.InvariantCulture));
sqlC.Parameters.AddWithValue("@type", type);
sqlC.Parameters.AddWithValue("@start", start);
sqlC.Parameters.AddWithValue("@end", end);
sqlC.Parameters.AddWithValue("@descr", descr);
sqlC.Parameters.AddWithValue("@msg", msg);
sqlC.Parameters.AddWithValue("@success", (success ? "1" : "0"));
try
{
sqlC.ExecuteNonQuery();
}
catch (SqlException)
{
sqlC.Dispose();
throw;
}
sqlC.Dispose();
}
答案 0 :(得分:7)
如果使用using
编写,此代码将更短,更正确。
有几种方法可以在不正确处理sqlC
的情况下转义函数。 .NET使用半同步异常模型,实际上任何托管代码行都可以抛出(例如ThreadAborted
异常)。或者sqlC.ExecuteNonQuery()
可能会抛出不同类型的异常。
答案 1 :(得分:2)
鉴于你只捕获一个异常(即使你重新抛出它) - 如果发生任何异常,你的try / catch块将被执行后没有任何异常。异常会中断正常流程,因此异常执行后没有任何内容。 (除非它在一个catch块中用于正确的异常,或者是一个finally块...)
如果您想确保在try / catch之后始终执行代码,请在块的末尾使用finally
。
但就IDisposable对象而言,using
块会为你处理这个问题,正如Ben Voigt所说。