[英]VS2010: Code analysis warning CA2000. Object is not disposed along all exception paths
In my goal to make good code, I've validated my project in Visual Studio 2010 using "Run Code analysis". 为了编写良好的代码,我使用“运行代码分析”在Visual Studio 2010中验证了我的项目。 In the below function I get the following warning that I dont understand, because the only row that can generate an exception is sqlC.ExecuteNonQuery() , with the only exception type " SQLException ". 在下面的函数中,我得到以下我不理解的警告,因为唯一可以生成异常的行是sqlC.ExecuteNonQuery() , 唯一的异常类型为“ SQLException ”。
CA2000 : Microsoft.Reliability : In method 'Company.log(string, string, DateTime, DateTime, string, bool)', object 'sqlC' is not disposed along all exception paths. CA2000:Microsoft.Reliability:在方法“ Company.log(字符串,字符串,DateTime,DateTime,字符串,bool)”中,对象“ sqlC”未沿所有异常路径放置。 Call System.IDisposable.Dispose on object 'sqlC' before all references to it are out of scope. 在对对象'sqlC'的所有引用超出范围之前,请调用System.IDisposable.Dispose。
Why does the Analysis complain? 为什么分析会抱怨? Any help is much appreciated! 任何帮助深表感谢!
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();
}
Go read about using
blocks 阅读有关using
块的信息
This code will get shorter and more correct if written with using
. 如果using
编写,此代码将变得更短,更正确。
There are several ways for exceptions to escape the function without disposing sqlC
properly. 有几种方法可以使异常逃逸该函数而不正确处理sqlC
。 .NET uses an semi-synchronous exception model, and in fact ANY line of managed code can throw (eg a ThreadAborted
exception). .NET使用半同步异常模型,实际上任何托管代码行都可以抛出(例如ThreadAborted
异常)。 Or sqlC.ExecuteNonQuery()
could throw a different type of exception. 或sqlC.ExecuteNonQuery()
可能引发不同类型的异常。
Given that you're only catching one exception (and even then you re-throw it) - in the event of any exception nothing after your try/catch block will be executed. 假设您只捕获一个异常(甚至重新捕获它),则在发生任何异常的情况下,将在try / catch块之后执行任何操作。 Exceptions interrupt the normal flow, so nothing after the exception gets executed. 异常会中断正常流程,因此在执行异常后什么也不会执行。 (Unless it's in a catch block for the right kind of exception, or a finally block...) (除非它位于catch块中以获取正确的异常,或者是finally块...)
If you want to ensure code is always executed after a try/catch, use finally
at the end of the block. 如果要确保在try / catch之后始终执行代码,请在代码块末尾使用finally
。
But in the case of IDisposable objects, using
blocks handle this for you as Ben Voigt says. 但是对于IDisposable对象, using
Ben块就像Ben Voigt所说的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.