jpoh
jpoh

Reputation: 4586

How do I dispose an IDisposable object if the using statement throws an exception?

How can I make sure in the following code snippet that IDataReader is disposed of if ExecuteReader throws an exception?

using (IDataReader rdr = cmd.ExecuteReader())
{
    // use it
}

It makes sense to me that the using syntatic sugar does not call Dispose (since there is no instance to call it on). However, how can I be sure that the scarce resources that are normally allocated by classes that implement IDisposable will be releases?

Upvotes: 4

Views: 961

Answers (4)

Frederik Gheysels
Frederik Gheysels

Reputation: 56934

I thought that the using statement was translated to the IL that is similar to:

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

So, I would think that in normal circumstances, the Dispose should be called ?

Also, you should not throw exceptions inside the constructor , as users will not expect that an exception will be thrown when they instantiate an object. I would move the initialization logic that can throw an exception to another method (Initialize) that has to be called after instantiating the object.

Upvotes: -2

user20155
user20155

Reputation: 1044

How about moving the code that does the initialization outside the constructor into a separate function. In essence you'll have

using (var tc = new TestClass())
{
    tc.Initialize();  // setup the object. acquire expensive resources here, etc.

    ..more code ..
}

Upvotes: 0

Matt Howells
Matt Howells

Reputation: 41266

If the constructor of an object fails to run then you do not have an object that needs to be disposed.

If you are writing a constructor which could throw an exception, you had better make sure you clean up anything you need to by using using or try-catch block.

In your IDataReader example, it is sufficient to simply dispose of the command object if the cmd.ExecuteReader() method call fails.

Upvotes: 3

sisve
sisve

Reputation: 19781

If ExecuteReader, in your example, throws an exception it never returns anything. It is then up to the implementation of ExecuteReader to dispose of anything created before the exception.

Upvotes: 14

Related Questions