The Second Rule of Implementing IDisposable and Finalizers
• CommentsFor a class owning managed resources, implement IDisposable (but not a finalizer)
IDisposable only has one method: Dispose. This method has one important guarantee: it must be safe to call multiple times.
An implementation of Dispose may assume that it is not called from a finalizer thread, that its instance is not being garbage collected, and that a constructor for its instance has completed successfully. These assumptions makes it safe to access other managed objects.
One mistake is to place a finalizer on a class that only has managed resources; this example code can result in an exception on the finalizer thread, which would crash the application:
Whether or not SingleApplicationInstance implements IDisposable, the fact that it’s accessing a managed object in its finalizer is a recipe for disaster.
Here’s an exmple of a class that removes the finalizer and then implements IDisposable in a correct but needlessly complex way:
When a class owns managed resources, it may forward its Dispose call on to them. No other code is necessary. Remember that some classes rename “Dispose” to “Close”, so a Dispose implementation may consist entirely of calls to Dispose and Close methods.
An equivalent - and simpler - implementation is here:
This IDisposable.Dispose implementation is perfectly safe. It can be safely called multiple times, because each of the IDisposable implementations it invokes can be safely called multiple times. This transitive property of IDisposable should be used to write simple Dispose implementations like this one.