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.

Implementing IDisposable

In the IDisposable and using in C# post I showed how to handle an object that implements IDisposable. That’s the most common scenario, where a simple using will ensure that resources are properly and early released, but that only handles the case when the resource is created and disposed of in the same function. What if the resource is a member of a class?

I have created a simple logging class that writes an opening line whenever the log is opened.

public class LogWriter
{
    private StreamWriter m_Stream;
 
    public LogWriter(string logFile)
    {
        m_Stream = new StreamWriter(logFile, true);
        m_Stream.WriteLine("Starting logging at {0}", DateTime.Now);
    }
 
    public void WriteLine(string message)
    {
        m_Stream.WriteLine(message);
    }
}

The StreamWriter created in the constructor implements IDisposable so we should call it’s Dispose method. But from where? The answer is to let the LogWriter implement IDisposable

Disposable Base Class

I have covered the IDisposable interface in my previous posts IDisposable and using in C# and Implementing IDisposable. To make the implementation of IDisposable easier, I have written an abstract base class that handles the details of the IDisposable pattern. The objectives of the class is to:

  • Provide a simple, reusable implementation of the disposable pattern.
  • Pass all code analysis rules.

Using and Disposing of WCF Clients

Designing an interface always requires careful considerations of how it will be used. Scott Meyers elegantly catches the entire problem in one sentence in his book Effective C++:

Make interfaces easy to use correctly and hard to use incorrectly.

The people at Microsoft who were in charge for the WCF client code generation either hadn’t read that book or didn’t understand it. They have made an interface that is counter intuitive and hard to use when it comes to disposing of the WCF client.

In my previous post IDisposable and using in C# I wrote that “Always call Dispose on objects implementing IDisposable“. This is true, as long as the class implements IDisposable in a reasonable way. Unfortunately the WCF client doesn’t. The MSDN docs presents the problem.

using (CalculatorClient client = new CalculatorClient())
{
    ...
} // <-- this line might throw
Console.WriteLine(
  "Hope this code wasn't important, because it might not happen.");

That is definitely an example of an interface that is hard to use. The hidden call to Dispose might throw with a strange exception which sometimes even hides the real error. There is a simple solution though that makes the above code work as expected.

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.