Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

AutoDisposer utility class

3.81/5 (8 votes)
15 Mar 20072 min read 1   100  
In this article you see how a simple class like the AutoDisposer can make programming a lot easier.

Screenshot - AutoDisposer.gif

Introduction

There are a lot of classes (in the .NET framework or perhaps your own classes) that implement the interface IDisposable in order to release allocated unmanaged resources. When a user instantiates such a class then he must call the method 'Dispose' when he is done with that instance of the class. Following this pattern can easily result in a lot of code, because this pattern should be used with a try-finally block (or a using statement). This article describes the AutoDisposer utility class that can reduce a lot of this code, making your code more readable.

Background

Consider the following code (samplecode1):

C#
private void ClaimResourcesOld()
{
    ManualResetEvent resetEvent = new ManualResetEvent(true);
    try
    {
        Brush drawingBrush = new SolidBrush(Color.FromArgb(50, Color.Purple));
        try
        {
            .....
        }
        finally
        {
            drawingBrush.Dispose();
        }
    }
    finally
    {
        ((IDisposable)resetEvent).Dispose();
    }
}

Using two disposable objects leads to a nesting of try-finally blocks. Note that one could also write the same code with nested using statements, which reduces the amount of code already somewhat but the nested structure is still required. Isn't there a way that one could write code with the same functionality without the nesting and with less code? Yes there is; with a small utility class called AutoDisposer.

The AutoDisposer class

The AutoDisposer class is a small utility class that keeps track of a list of disposable objects. The class itself implements IDisposable and in the 'Dispose' of the class the tracked elements are disposed. The interface of the class is:

C#
public sealed class AutoDisposer : IDisposable
{
    public AutoDisposer() : this(false) { }
    public AutoDisposer(bool disposeReverse) { m_DisposeReverse = 
        disposeReverse; }

    public void Add(object obj) { ... }
}

The user must create an instance of the AutoDisposer class and add disposable objects through the 'Add' method. When disposing the instance of the AutoDisposer class all the tracked disposable objects are disposed in the order that they are added. This order can also specified by the user when the overloaded second constructor of the AutoDisposer class is used.

When searching on the internet I found the article Writing Better Software: Managing Unmanaged Resources which also talks about an AutoDisposer class, which has a stack-based implementation for tracking disposable objects. The AutoDisposer class of this article differs on the following issues

  • All types of objects can be added, not only objects of type IDisposable
  • The disposable objects are tracked with a list, where the used can specify the order in which to dispose the tracked objects
  • The class also deals with disposable null objects, the user doesn't have to check the validness of the disposable object when adding it
This results in an easier to use utility class.

Using the code

When using the AutoDisposer class samplecode1 can be changed to the following code (samplecode2):

C#
private void ClaimResourcesNew()
{
    using (AutoDisposer autoDisposer = new AutoDisposer())
    {
        ManualResetEvent resetEvent = new ManualResetEvent(true);
        autoDisposer.Add(resetEvent);
        Brush drawingBrush = new SolidBrush(Color.FromArgb(50, Color.Purple));
        autoDisposer.Add(drawingBrush);
        .....
    }
}

As you can see, this reduces the code drastically and makes the code more readable.

Summary

Reading this article should have made you aware how a small utility class as the AutoDisposer can make your life easier. Any comments or questions post below or e-mail them.

History

Version 1.0 - This is the first version of this article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here