简体   繁体   中英

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". 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 ".

CA2000 : Microsoft.Reliability : In method 'Company.log(string, string, DateTime, DateTime, string, bool)', object 'sqlC' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'sqlC' before all references to it are out of scope.

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

This code will get shorter and more correct if written with using .

There are several ways for exceptions to escape the function without disposing sqlC properly. .NET uses an semi-synchronous exception model, and in fact ANY line of managed code can throw (eg a ThreadAborted exception). Or sqlC.ExecuteNonQuery() could throw a different type of exception.

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. 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...)

If you want to ensure code is always executed after a try/catch, use finally at the end of the block.

But in the case of IDisposable objects, using blocks handle this for you as Ben Voigt says.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM