Home > Code Generation, Coding Helpers > Implementing the IDisposable pattern using CodeRush

Implementing the IDisposable pattern using CodeRush

August 15th, 2012

The IDisposable Pattern is used to release and close unmanaged resources such as files, streams, and handles as well as references to managed objects that use unmanaged resources, held by an instance of the class. For classes that require a resource cleanup, we recommended following the IDisposable pattern, which provides a standard and unambiguous pattern. The pattern has been designed to ensure reliable, predictable cleanup, and to prevent temporary resource leaks.

There are several options to consider when implementing the IDisposable pattern. Let’s take a look at the following code sample:

CodeRush Implement IDisposable sample code

The problem with this class is that StreamReader and StreamWriter objects use unmanaged resources. If this class is instantiated, and the later is allowed to simply go out of scope, the objects may not be cleaned up immediately and resources will be locked unnecessarily.

To implement the IDisposable pattern, we should first specify the corresponding interface as one of those that our class implements:

Implement IDisposable Pattern - first step

The interface contains only a single Dispose method. This is what the public Dispose() method implementation looks like:

Implement IDisposable first Dispose method

The method calls the second parameterized Dispose() method, passing ‘true’ as an argument to indicate that the method has been called manually. Then, it calls the SuppressFinalize() method of the garbage collector, which prevents the finalizer from executing and limits any associated performance degradation, because finalization increases the cost and duration of your object’s lifetime since each finalizable object must be placed on the finalization queue when it is allocated.

The order of two calls inside the Dispose is important, as it ensures that the GC.SupressFinalize()call is only invoked if the Dispose operation is completed successfully. When Dispose calls Dispose(true), the call may fail while an exception is thrown, but when Finalize is called later, it calls Dispose(false). In reality, these are two different calls can execute different portions of the code, even though Dispose(true) fails, Dispose(false) may not.

The second version of the Dispose(bool disposing) method accepts a Boolean parameter that indicates whether the code has been called manually or automatically. If called manually, all managed and unmanaged resources can be released. If the method was called automatically via the garbage collection process, the managed resources will already have been dealt with, so only the unmanaged resources are cleared.

When implementing the Dispose method, we must ensure that all held resources are freed by propagating the call through the containment hierarchy. To give the base classes a chance to cleanup resources, it is required to invoke the base class’ Dispose(bool disposing) method as the last operation, if one is available. Make sure to pass the same value of ‘disposing’ to the base class’ method.
So, the method implementation for the Logger class looks like this:

Implement IDisposable second Dispose method

Because the Dispose method must be called explicitly, objects that implement IDisposable must also add a finalizer, if a class contains unmanaged resources, to handle the release of those resources when Dispose is not called. The finalizer must utilize the Dispose method with the ‘disposing’ parameter set to ‘false’. The false value indicates that the method was not called manually:

Implement IDisposable finalizer

Don’t forget to declare the _Disposed field as follows which indicates the state of the object whether it is disposed or not:

CodeRush Implement IDisposable field declaration

As always, CodeRush provides a couple of code providers that allow you to easily implement the IDisposable pattern without having to remember the entire pattern, using the corresponding Implement IDisposable code provider available on the class name:

CodeRush Implement IDisposable preview

you can automatically generate the required code to release all unmanaged resources. Just choose the position where you would like to put the pattern’s code:

CodeRush Implement IDisposable select target

and you are done:

CodeRush Implement IDisposable result

If you later create new fields that should be disposed, you can utilize the Dispose Fields code provider:

CodeRush Dispose Fields preview

As a result, the Dispose Fields code provider will add the required disposal code for the specified field as illustrated in the preview hint above.

Using Disposable Objects

Implementing the IDisposable pattern is very important when creating objects that hold disposable resources, but this pattern does not dictate you how to use an instance of the resulting class. Unfortunately, there is no way to force developers to call Dispose explicitly when they are done using it, or to force them to use the proper exception handling mechanism to make sure that the Dispose is called even when an exception is thrown.

So, when you use an object that accesses unmanaged resources, it is a good practice to create the instance with a using statement. The using statement automatically calls the Dispose method on the object when the code that is using it has completed. You can create a using statement by utilizing the Introduce Using Statement code provider. For instance, for this code:

CodeRush Implement IDisposable - Introduce Using Statement sample code

the code provider will produce the following code:

CodeRush Implement IDisposable - Introduce Using Statement result

Once a class has been disposed, all of its resources should be considered as unreachable. Attempts to continue using the class may be invalid and should be prevented. If the object has been disposed, we can throw an ObjectDisposedException, providing the object name, to indicate the error. This check should be made in all public members of the class.

Products: CodeRush Pro
Versions: 12.1 and up
VS IDEs: 2008 and up
Updated: Aug/17/2012
ID: C179

Similar Posts:

  1. August 17th, 2012 at 04:21 | #1

    “Because the Dispose method must be called explicitly, objects that implement IDisposable *must* also add a finalizer to handle release of resources when Dispose is not called.”

    Not quite correct. Finalizer is required only for releasing unmanaged resources and it isn’t directly tied to IDisposable. IOW if class doesn’t use unmanaged resources then it shouldn’t have a finalizer in first place – it is just a performance hit.

  2. August 17th, 2012 at 07:30 | #2

    Hi Miha,
    You are correct. Thank you for the pointer. I’ll modify this sentence.

  3. August 18th, 2012 at 05:26 | #3

    Hi Alex. I have translated your nice article and published on the following URL:

  4. August 18th, 2012 at 09:46 | #4

    Thank you very much, Hideaki!