tags:

views:

93

answers:

3

If I use "using" construct, I know that the object gets automatically disposed. What happens if a statement inside an "using" construct raises an exception. Is the "using" object still disposed? If so, when?

+10  A: 

A using block is converted - by the compiler - to this:

DisposableType yourObj = new DisposableType();
try
{
    //contents of using block
}
finally
{
    ((IDisposable)yourObj).Dispose();
}

By putting the Dispose() call in the finally block, it ensures Dispose is always called - unless of course the exception occurs at the instantiation site, since that happens outside the try.

It is important to remember that using is not a special kind of operator or construct - it's just something the compiler replaces with something else that's slightly more obtuse.

Rex M
It's also important to note that, as your example illustrates, if the call to DisposableType() throws an exception, Dispose() won't be called; any resources allocated there prior to the exception won't be released.
Ben
@Ben very true. I'll explicitly point that out.
Rex M
There's a `null`-test in the `finally` block as well.
Ani
+1 This is exactly what it says in the manual, of course. http://msdn.microsoft.com/en-us/library/yh598w02.aspx
MarkJ
+1  A: 

This article explains it nicely.

Internally, this bad boy generates a try / finally around the object being allocated and calls Dispose() for you. It saves you the hassle of manually creating the try / finally block and calling Dispose().

Nayan
+2  A: 

Actually Using block is Equivalent to try - finally block, Which ensures that finally will always execute e.g.

using (SqlConnection con = new SqlConnection(ConnectionString))
{
    using (SqlCommand cmd = new SqlCommand("Command", con))
    {
        con.Open();
        cmd.ExecuteNonQuery();
    }
}

Equals to

SqlConnection con =  null;
SqlCommand cmd = null;

try
{
    con = new SqlConnection(ConnectionString);
    cmd = new SqlCommand("Command", con);
    con.Open();
    cmd.ExecuteNonQuery();
}
finally
{
    if (null != cmd);
        cmd.Dispose();
    if (null != con)
        con.Dispose();
}
Azhar