Exception Safety and IDisposable Factories

C# is mostly relieved from the stress of exception safety, thanks to garbage collections. But in some cases it must be handled. A common case is factories creating more than one IDisposable object.

Coming from a C++ background, the notion of exception safety is natural to me. For a C++ developer exception safety is as important as… as… ehhmm… I can’t really find any equivalent in C#. I guess that’s good because exception safety is a pain to deal with. The most common reason to care about exception safety in C++ is memory management and in C# that is a non issue thanks to the garbage collector. For other resources C# offers the using construct and in 95% of the cases it deals with the messy details of ensuring that the resource is disposed even in the event of an exception.

Unfortunately there are those 5% that isn’t handled by the using statement. In this post I’ll use a constructor that allocates a precious resource in the form of objects implementing IDisposable. The principle is the same however for any function that creates a IDisposable object whose lifetime will exceed the function execution.

The Problem

Let’s get to some code. This is a simple class holding a precious resource. To make sure that the precious resource is disposed as soon as it is no longer used, the class implements IDisposable (not using the proper full pattern now, to keep the code shorter).

public class NotExceptionSafe : IDisposable
{
    private readonly PreciousResource resource;
 
    public NotExceptionSafe()
    {
        resource = new PreciousResource();
        resource.Open();
    }
 
    public void Dispose()
    {
        resource.Dispose();
    }
}

PreciousResource writes debug output in both the constructor and the Dispose method so we can see that it is properly disposed of. Let’s run the code and test it and see how the resource is allocated and released.

Allocated precious resource.
Caught InvalidOperationException exception (Failed opening!)

Ooopss… it’s only allocated. Then the test runner catches an exception from the Open method.

The problem is that since the NotExceptionSafe instance is never fully constructed it won’t be disposed by the using block (because no object will ever be fully constructed and returned to the using). If the constructor fails, then we’re on our own to handle it.

IDisposable and using in C#

C# and the .NET environment have automatic memory management through garbage collection. Coming from C++ I think it’s great to not having to worry about memory deallocation. Unfortunately memory from the managed heap (which is where C# objects are placed)  is just one kind of resource in a system. There are several other types of resources:

  • File handles
  • Network sockets
  • Database connections
  • Unmanaged memory

These resources still need to be freed in C#. If the .NET class handling the resource is implemented correctly it will release the unmanaged resource when the object is garbage collected. This is fine as long as it doesn’t matter when the resource is freed. In a program with small memory footprint the garbage collector might never run during the execution of the program, because the low memory usage never triggers a run. In the meantime your program can hold on to an expensive database connection instead of releasing it back to the connection pool for reuse. Eventually the database connection pool is empty and your program (or web site) will start failing.

Software Development is a Job – Coding is a Passion

I'm Anders Abel, an independent systems architect and developer in Stockholm, Sweden.

profile for Anders Abel at Stack Overflow, Q&A for professional and enthusiast programmers

Code for most posts is available on my GitHub account.

Popular Posts

Archives

Series

Powered by WordPress with the Passion for Coding theme.