Gordon Thompson
Gordon Thompson

Reputation: 4834

C# "Using" Syntax

Does the using catch the exception or throw it? i.e.

using (StreamReader rdr = File.OpenText("file.txt"))
{
 //do stuff
}

If the streamreader throws an exception is it caught by using or thrown so the calling function can handle it?

Upvotes: 51

Views: 35574

Answers (11)

Branko Dimitrijevic
Branko Dimitrijevic

Reputation: 52107

In your example, if File.OpenText throws, the Dispose will not be called.

If the exception happens in //do stuff, the Dispose will be called.

In both cases, the exception is normally propagated out of the scope, as it would be without the using statement.

Upvotes: 3

jop
jop

Reputation: 84043

When you see a using statement, think of this code:

StreadReader rdr = null;
try
{
    rdr = File.OpenText("file.txt");
    //do stuff
}
finally
{
    if (rdr != null)
        rdr.Dispose();
}

So the real answer is that it doesn't do anything with the exception thrown in the body of the using block. It doesn't handle it or rethrow it.

Upvotes: 66

FlySwat
FlySwat

Reputation: 175593

using statements do not eat exceptions.

All "Using" does is scope your object to the using block, and automatically calls Dispose() on the object when it leaves the block.

There is a gotcha though, if a thread is forcefully aborted by an outside source, it is possible that Dispose will never be called.

Upvotes: 36

Jeffrey L Whitledge
Jeffrey L Whitledge

Reputation: 59463

Any exceptions that are thrown in the initialization expression of the using statement will propagate up the method scope and call stack as expected.

One thing to watch out for, though, is that if an exception occures in the initialization expression, then the Dispose() method will not be called on the expression variable. This is almost always the behavior that you would want, since you don't want to bother disposing an object that was not actually created. However, there could be an issue in complex circumstances. That is, if multiple initializations are buried inside the constructor and some succeed prior to the exception being thrown, then the Dispose call may not occur at that point. This is usually not a problem, though, since constructors are usually kept simple.

Upvotes: 4

petr k.
petr k.

Reputation: 8100

You can imagine using as a try...finally block without the catch block. In the finally block, IDisposable.Dispose is called, and since there is no catch block, any exceptions are thrown up the stack.

Upvotes: 1

Joel Coehoorn
Joel Coehoorn

Reputation: 415735

using guarantees* the object created will be disposed at the end of the block, even if an exception is thrown. The exception is not caught. However, you need to be careful about what you do if you try to catch it yourself. Since any code that catches the exception is outside the scope block defined by the using statement, your object won't be available to that code.

*barring the usual suspects like power failure, nuclear holocaust, etc

Upvotes: 2

stephenbayer
stephenbayer

Reputation: 12431

It throws the exception, so either your containing method needs to handle it, or pass it up the stack.

try
{
    using (
        StreamReader rdr = File.OpenText("file.txt"))
    { //do stuff 
    }
}
catch (FileNotFoundException Ex)
{
    // The file didn't exist
}
catch (AccessViolationException Ex)
{
    // You don't have the permission to open this
}
catch (Exception Ex)
{
    // Something happened! 
}

Upvotes: 6

harpo
harpo

Reputation: 43168

"using" does not catch exceptions, it just disposes of resources in the event of unhandled exceptions.

Perhaps the question is, would it dispose of resources allocated in the parentheses if an error also occured in the declaration? It's hard to imagine both happening, though.

Upvotes: 0

tpower
tpower

Reputation: 56886

The using does not interfere with exception handling apart from cleaning up stuff in its scope.

It doesn't handle exceptions but lets exceptions pass through.

Upvotes: 4

Chris Marasti-Georg
Chris Marasti-Georg

Reputation: 34650

using allows the exception to boil through. It acts like a try/finally, where the finally disposes the used object. Thus, it is only appropriate/useful for objects that implement IDisposable.

Upvotes: 16

hometoast
hometoast

Reputation: 11782

If you don't specifically catch an exception it's thrown up the stack until something does

Upvotes: 2

Related Questions