Using, IDisposable and Such

I was messing with a PDF generating class (PDFSharp, an excellent free .NET PDF Toolkit for creating PDF’s) and had to create a class that will load up some images (logos, watermarks, etc.) and then use those for the PDF. The problem is that these type objects are GDI+ type objects and are unmanaged objects. This became a problem because the logos I created during the PDF generation would remain in an opended state by the PDF generation class. This prevented me from deleting the logo file and just really pissed me off.

So IDisposable to the rescue. This allows me to manually manage the disposal of the unmanaged objects and then I could implement the PDF generation class in a using and viola! I was able to delete the image file with no issues.

Here and Here are a couple of great websites with notes and hints about implementing the IDisposable interface in C#. 

The only part that got me is the Finalizer and realizing that the Finalizer is called when the object is destructed by the GC. This is not safe to assume this is at the same time that the object is being disposed (end of a Using statement). So that is why some of the examples you find will have a Dispose(false) to a Dispose method. This prevents the managed objects from being collected in the destructor as the order is unpredictable. If that makes sense to you, great!

Here is a very simple class implementing the IDisposable interface;

[code:c#]
public class PDFMaker : IDisposable 
{
    // some fields that require cleanup
    private SafeHandle handle;
    // this is the Handle to the GDI+ object     
    private bool disposed = false; 
    // to detect redundant calls      
    public PDFMaker()     
    {         
        this.handle = /*…*/;
        // Cheezy example     
    }
    public void MakePDF()  
    {   
        // Do something cool here and make a PDF    
    }
    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                if (handle != null)
                    handle.Dispose();
            }
            disposed = true;
        }
    }
    public void Dispose()
    {
        Dispose(true);
    }
}
[/code]

Enjoy!