views:

514

answers:

2

In the example below, is connection going to close and dispose when exception is thrown if it is within using statement?

using (var conn = new SqlConnection("..."))
{
    conn.Open();
    // stuff happens here and exception is thrown...
}

I know this code below will make sure that it does, but I'm curious how using statment does it.

var conn;
try
{
    conn = new SqlConnection("...");
    conn.Open();
    // stuff happens here and exception is thrown...
}
// catch it or let it bubble up
finally
{
    conn.Dispose();
}

Related:

http://stackoverflow.com/questions/141204/what-is-the-proper-way-to-ensure-a-sql-connection-is-closed-when-an-exception-is

+5  A: 

Yes, using wraps your code in a try/finally block where the finally portion will call Dispose() if it exists. It won't, however, call Close() directly as it only checks for the IDisposable interface being implemented and hence the Dispose() method.

See also:

Jeff Yates
Just to point out on the connection classes if you reflector over them you will see Dispose() does indeed internally call Close(). If it's in a state it can.
Chris Marisic
You are correct, it does. However, I deliberately didn't mention it as I didn't want to mislead anyone to think this has anything to do with IDisposable or the associated pattern. The fact that this particular implementation calls Close() is a detail of the implementation, not the pattern.
Jeff Yates
+2  A: 

This is how reflector decodes the IL generated by your code:

private static void Main(string[] args)
{
    SqlConnection conn = new SqlConnection("...");
    try
    {
        conn.Open();
        DoStuff();
    }
    finally
    {
        if (conn != null)
        {
            conn.Dispose();
        }
    }
}

So the answer is yes, it will close the connection if

DoStuff()
throws an exception.

Florin Sabau
Add if conn.Open() throws an exception. :D
Jeff Yates
Yeah sure. If whatever is in the block AFTER the using clause throws an exception, the connection will be closed. The only way the finally block won't be executed is if the "new SqlConnection(...)" throws, but in that case you wouldn't have actually a valid open connection to close. So it's fine.
Florin Sabau