Monday, September 28, 2009

IDisposable is a Developer Convention

Given the following bit of code, when does the Dispose method of Trash get called?

using System;

namespace Dispose
{
public class Trash : IDisposable
{

#region IDisposable Members

public void Dispose()
{
Console.WriteLine("I am being disposed");
}

#endregion
}


class Program
{
static void Main(string[] args)
{

var c = new Trash();


}
}
}


 



Answer



Never



The IDisposable interface is a developer convention and is not enforced by the .NET runtime.  IDisposable is not called by the .NET runtime on the developer behalf (at the time of this writing).  IDisposable exists to help model a more explicit (deterministic) method for releasing of memory for .NET developers.  See Implementing Finalize and IDisposable to Clean Up Unmanaged Resources



Some might say that it was a warm and fuzzy blanket used to swathe all the C++ programmers in as they transitioned into .NET.  That may be the case, but inevitably, as a developer, you will need a way to declare your intent that your class has resources that need to be cleaned up now. Traditionally, this has been to represent unmanaged resources but it doesn’t have to be.  So, if you see a class that implements IDisposable, consider it good form to go ahead and invoke Dispose as soon as your finished with the object. 



An Exception for Every Rule



The exception to the rule is when working with WCF proxies.  This well known design pattern of IDisposable is broken in a bad way. For some good information as to why try a search WCF IDisposable is broken.  The nut of which is if you call Dispose on a WCF proxy, and the channel has already been faulted, you’ll never see the originating fault because of the proxies implementation of Dispose just tries to Close the channel, which throws a new exception, and stomps all over the call stack of the original exception. 



Your damned if you do call Dispose (might lose useful error information) and your damned if you don’t (hold server resources open longer than required).  Many of the links in the search query will return useful ways to get around the problem, but it would be nice if, as a community, we adopted one of these solutions.



This has been a .NET public service announcement.  You may now return to your regularly scheduled programming.