IDisposable Pattern

When I started out with .NET, I wasn’t quite happy with the documentation provided
for the IDisposable interface by Microsoft. The examples always
depicted some class using an unmanaged resource that needed to be evicted from
memory. To achieve this, said class implemented IDisposable, a
finalizer and a Dispose(bool disposing) that was called from both
the finalizer and the IDisposable.Dispose() method.

But it didn’t tell me that you don’t need the whole disposable pattern with a
finalizer and Dispose(bool disposing) method unless your class
actually owns an unmanaged handle directly. Or that adding a finalizer to a
class means each instance of it is tracked in a finalization queue, which means
more work for the garbage collector.

This article will introduce you to the disposable pattern the way I would have
wished for when I switched to .NET!

Why Dispose?

.NET is a runtime environment based on garbage collection. That means instead
of allocating memory, using it and then freeing it again, you can just allocate away
and when your program has no more references to the allocated memory, .NET will
free it for you automatically.

This is done by the garbage collector. It will run every now and then, check which
objects your application is no longer referencing (so called “garbage”) and reclaim
the resources used by those objects.

This works great for memory, but what if the object in question is a file? Open
the file, write to it and then… just let it go. It will eventually be closed —
but you don’t know when the garbage collector will come around to do it. So the
file stays locked until this happens. Not good if you’re writing an image editor
where the user might want to use the image file after he saved it.

By explicitly disposing objects, you can tell .NET that you want a resource freed
right here and now.

IDisposable

The IDisposable interface is just an interface with a single method
named Dispose(), nothing more. It has no special meaning for the
.NET runtime and implementing it will not change your object’s behavior at all.

All it’s good for is to provide a standardized way for you to tell an object to
release its resources. The C# language even provides some built-in support for
IDisposable. Instead of writing:

As stated before, this is a pure C# language feature that will be rewritten to
something resembling the former code example when it is compiled to IL code.

Finalizers

Finalizers are special methods that get called when an object is collected by
the garbage collector. They can be seen as an emergency path to release unmanaged
resources if the user of an object forgot to call IDisposable.Dispose()
on it.

Adding a finalizer to a class means that whenever you create an instance of said
class, that instance will be added to a global finalization queue that tells the
garbage collector not to reclaim the object’s memory until its finalizer has been
executed. This of course means additional management overhead.

That’s why you often see this little trick in classes with a finalizer:

class MyClass : IDisposable {/// <summary>Finalizer that will be called by the GC</summary>
~MyClass(){
ReleaseUnmanagedResources();}/// <summary>Immediately releases all resources owned by the object.</summary>publicvoid Dispose(){
ReleaseManagedResources();
ReleaseUnmanagedResources();// We have released our resources already. Tell the GC that it// doesn't need to call the finalizer anymore.
GC.SuppressFinalize(this);}}

GC.SuppressFinalize() removes the instance from the finalization
queue, so the garbage collector can now reclaim the object without waiting for
its finalizer to be executed.

Notice

Do not access any other objects in your finalizer!

When the finalizer is called, you do not know if any other objects being
referenced are still alive. Also do not call the Dispose() method
on any other objects in your finalizer – they may be gone already.

Simplified Disposable Pattern

You can support the disposable pattern to two different degrees. This simplified
variant is the one you should prefer as long as your class is not the direct owner
of an unmanaged resource.

Use it whenever you need to call Close() on a FileStream,
unregister from an event or when your class owns another object that implements
IDisposable (which might even be an object that wraps an unmanaged
resource itself and requires the full disposable pattern)

You can implement IDisposable in a very simple manner by only adding
IDisposable to the list of interfaces for your class and writing
the finalization code directly into the Dispose() body:

Example

Let’s take an example from my favorite topic, game programming, and check out
how IDisposable could be used in a real-world scenario that doesn’t
have anything to do with unmanaged resources!

Let’s see:

The Game class can load levels asynchronously

While it is loading, Game regularly triggers the
LoadingProgressUpdated event to notify its subscribers about
the achieved progress

The LoadingScreen class subscribes to the Game‘s
LoadingProgressUpdated event

Looks like the perfect construction kit for a game with a loading screen!

Now what if the level has been loaded and the loading screen is no longer needed?
Thanks to the gargabe collector we could just drop it, right?

Right. Except that the garbage collector will not reclaim the
LoadingScreen because it’s still subscribed to the
Game.LoadingProgressUpdated event (in other words, the
Game class still has a reference to it).

And that, when the player finishes the level and we set up another loading screen
for the next level being loaded, it will still be registered. In level 10, the
Game class will already have 10 LoadingScreens subscribed
to it. Oops.

That’s where we could use IDisposable: Let the
LoadingScreen implement IDisposable and unsubscribe from the
event when it’s disposed. Then take care to call LoadingScreen.Dispose
after a level has finished loading and everything is fine.

Full Disposable Pattern

This is the IDisposable implementation you will see demonstrated
in the MSDN docs and that a lot of developers have come to accept as the only
way to add finalization code to a class. It is only required in the specific case
where a class directly owns an unamaneged resource handle.

class MyClass : IDisposable {/// <summary>Finalizer that will be called by the GC.</summary>
~MyClass(){
Dispose(false);// false == called by the GC}/// <summary>Immediately releases all resources owned by the object.</summary>publicvoid Dispose(){
Dispose(true);// true == called explicitly by user code// We have released our resources already. Tell the GC that it// doesn't need to call the finalizer anymore.
GC.SuppressFinalize(this);}/// <summary>Immediately releases all resources owned by the object.</summary>/// <param name="calledExplicitly">/// If true, the object is being disposed explicitly and can still access/// other managed objects it is referencing. If false, other managed objects/// maybe have been destroyed already and mustn't be touched./// </param>protectedvirtualvoid Dispose(bool calledExplicitly){if(calledExplicitly){// Perform finalization of managed objects here}// Perform finalization of unmanaged objects here}}

As you might have noticed, I took the liberty of renaming the disposing
parameter you will find in the MSDN example to calledExplicitly.
That’s because having a parameter named disposing in a method named
Dispose() doesn’t exactly light a candle to me 😉

The important thing to note here is that managed resources will only be disposed
if the Dispose(bool calledExplicitly) method is invoked by an
explicit call through IDisposable.Dispose(). This is important because,
as mentioned before, if the method is being executed through the finalizer,
it must not access any other objects, not even to call Dispose()
on them – they may have already been destroyed.

Example

Here’s an example demonstrating the use of the full disposable pattern with
a finalizer and everything:

What do we have here?

A DatabaseConnection class that communicates with some proprietary
database engine through a “pipe”

Said “pipe” is an unmanaged resource that needs to be closed, so the
DatabaseConnection class implements the full disposable pattern.

A DatabaseWriter class the owns a DatabaseConnection
instance. It implements the lightweight disposable pattern.

Without the finalizer (DatabaseConnection.~DatabaseConnection()),
if the programmer forgot to call Dispose() on his
DatabaseConnection, the pipe would never be closed since the garbage
collector doesn’t know what to do with the IntPtr.

But with the finalizer in place, the garbage collector will call it and be able
to close the pipe even if the programmer forgot to do so explicitly.

The DatabaseWriter class doesn’t have a finalizer. It couldn’t do
anything in it anyway – calling DatabaseConnection.Dispose() would
be risky because the DatabaseConnection could already be destroyed
at this point.

So DatabaseWriter uses the lightweight dispose pattern and disposes
the DatabaseConnection only if it is explicitly called.

Very good synthesis. I would INSIST on one (fundametal imo) point: with SafeHandle (that must be used everywhere) there is actually absolutely NO reason to have a finalizer.

I actually wrote only one: the class is TemporaryFile: the “unmanaged resource” is the path of the temporary file… As I wanted to cleanup (File.Delete) whenever the TemporaryFile object died, I had to implement the “classical” IDisposable pattern.

It is, for me, the only exception I’ve ever met to the rule “You do not need finalizers, lightweight IDisposable is enough”.

I’m currently only using it when I find myself duplicating code in my finalizers (in those cases where more than one .NET class uses the same type of unmanaged resource or several unmanaged resources have the same cleanup method).

But your generalization of always using a SafeHandle so that you only have to deal with finalizers in very special situations sounds like a good idea, too. It means one less thing to worry about when designing a class that interacts with unmanaged code!

Thanks very much, how much clearer things sometimes can be with a different naming of a parameter.

There’s still one thing where I struggle. IDisposable with inheritance, especially when the base class already provides virtual void Dispose(bool calledExplicitly).

Do I do my own bookkeeping or do I use protected bool IsDisposed { get; }? When overriding, base.Dispose(calledExplicitly) has to be called. At the beginning of mine or at the end? At the end, isn’t it?

After all, the derived class is building upon the base class, so it’s only logical that destruction should happen in the opposite order as construction. Like cleanly shutting down a thread that was created by the base class but is controlled by the derived class.

I usually do my bookkeeping implicitly per object instead of via an isDisposed flag, eg.