Kashif
Kashif

Reputation: 14440

Catch exceptions within a using block vs outside the using block - which is better?

Is there any difference between these tow pieces of code & which approach is better.

try
{
    using()
    { 
      //Do stuff
    }
}
catch
{
    //Handle exception
}


using()
{
    try
    {
         //Do stuff
    }
    catch
    {
        //Handle exception
    }
}

Upvotes: 32

Views: 10145

Answers (6)

Scott Wegner
Scott Wegner

Reputation: 7493

As mentioned above, only the first method will catch exceptions in the IDisposable object's initialization, and will have the object in-scope for the catch block.

In addition, the order of operations for the catch and finally blocks will be flipped depending on their nesting. Take the following example:

public class MyDisposable : IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("In Dispose");
    }

    public static void MethodOne()
    {
        Console.WriteLine("Method One");
        using (MyDisposable disposable = new MyDisposable())
        {
            try
            {
                throw new Exception();
            }
            catch (Exception ex)
            {
                Console.WriteLine("In catch");
            }
        }
    }

    public static void MethodTwo()
    {
        Console.WriteLine("Method Two");
        try
        {
            using (MyDisposable disposable = new MyDisposable())
            {
                throw new Exception();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("In catch");
        }
    }

    public static void Main()
    {
        MethodOne();
        MethodTwo();
    }
}

This will print:

Method One
In catch
In Dispose
Method Two
In Dispose
In catch

Upvotes: 2

Mark
Mark

Reputation: 10206

Ultimately, you could combine both methods to overcome both drawbacks:

IFoo f;
try{
  f = new Foo();
  f.Bar();
catch{
  // Do something exceptional with f
} finally{
  if(f != null) f.Dispose();
}

Upvotes: 2

Joel Coehoorn
Joel Coehoorn

Reputation: 416149

There are differences, but it namely boils down to the fact that a using block creates it own try and scope blocks.

try
{
    using(IDisposable A = GetDisposable())
    { 
      //Do stuff
    }
}
catch
{
    //Handle exception
    // You do NOT have access to A
}


using(IDisposable A = GetDisposable())  //exception here is uncaught
{
    try
    {
         //Do stuff
    }
    catch
    {
        //Handle exception
        // You DO have access to A
    }
}

Upvotes: 29

John Saunders
John Saunders

Reputation: 161831

I presume you mean:

using (var x = new Y(params))
{
}

In both cases? Then the obvious difference is the scope of x. In the second case, you could access x in the catch clause. In the first case, you could not.

I'll also take the opportunity to remind you not to "handle" an exception unless you can really do something about it. That includes logging the exception, which would be ok, unless the environment you're operating in does the logging for you (as ASP.NET 2.0 does by default).

Upvotes: 1

Adam Wright
Adam Wright

Reputation: 49396

Yes. In the first, the resource you are "using" will be disposed before the catch block is executed. In the later, it will be disposed afterwards. Moreover, the "foo" statement isn't under the scope of the catch clause. A "using" block is almost syntactic sugar such that

using (foo)
{
}

is

try
{
  foo;
}
finally
{
  foo.Dispose();
}

Which behaviour is "better" is not obvious without context.

Upvotes: 5

Darin Dimitrov
Darin Dimitrov

Reputation: 1039508

There's a difference between these blocks. In the second case the exception won't be caught if it is thrown in the using() line (for example instantiating an IDisposable object and the constructor throws an exception). Which one is better will depend on your specific needs.

Upvotes: 7

Related Questions