ILoggable

A place to keep my thoughts on programming

June 13, 2009 geek , , ,

When using won’t Dispose

The using statement/block in C# (not the one used to pull in namespaces) is meant to aid in the IDisposable pattern, i.e. cleaning up resources that won’t be handled by garbage collection and to do so in a deterministic fashion. I.e. everything that finalization is not. It really is just syntactic sugar to avoid try/finally all the time. I.e. this

using(var disposable = new DisposableObject())
{
  // do something with disposable
}

is pretty much the same as

var disposable = new Disposable();
try
{
  // do something with disposable
}
finally
{
  disposable.Dispose();
}

But there is a common pitfall with using, err, using. It’s in the first line above: The disposable object is created outside the try/finally block! Now, a constructor failing shouldn’t ever have allocated disposable resources, so you’re usually safe here. But beware if the construction of the Disposable object is a Method.

using(var disposable = CreateDisposable())
{
  // do something with disposable
}

If CreateDisposable() fails after it has created Disposable, you’ll end up with a resource leak!

You can easily avoid this by catching failure in your method and cleaning up, but you can’t use using for this purpose, since success would return an already disposed instance. A safe implementation of CreateDisposable() looks like this:

public Disposable CreateDisposable()
{
  Disposable disposable = new Disposable();
  try {
    // do some extra initialization of disposable
  }
  catch
  {
    if( disposable != null )
      disposable.Dispose();
    throw;
  }
  return disposable; 
}

IDisposable is an important pattern in .NET, but because it is a pattern rather than a construct enforced by the compiler, it is a common source of “leaks” in .NET. using is very useful for handling the disposable, but it is important to remember that the only code covered by the automatic disposition logic is the code inside the using block, not the code inside the using statement.

Leave a comment