views:

75

answers:

3

Is it really better not to use finalize compare to dispose ? Does dispose remove unmanaged resource in first parse ?

What is suppressing finalize ?

+4  A: 

Your implementation of IDisposable should be:

public MyClass : IDisposable
{
     public void Dispose() 
     {
         Dispose(true);
         GC.SuppressFinalize(this);
     }

     protected Dispose(bool disposing) 
     {
         if( disposing )
         {
             // release unmanaged resource
         }
         // release managed resources
     }

     ~MyClass() 
     {
         Dispose(false);
     }
}

If an object has a finalizer the CLR keeps a reference to it in the finalization queue. If you dispose manually the object (calling Dispose()) you already remove the unmanaged resources (as the implementation of dispose and the finalizer is shared), so there is no need to call the finalizer and you can safely remove the object from the finalization queue (calling GC.SuppressFinalize(this)).

munissor
Sigh, the myth that this is a common implementation of IDisposable is impossible to exorcise.
Hans Passant
Can you share any link about how to implement IDisposable correctly?
munissor
See my answer. :)
Stephen Cleary
Very good article, thank you Stephen!
munissor
The comments here are backwards. You should release managed resources if and only if disposing is true.
Matt Ellis
A: 

Typically both Dispose and Finalize will clean up any unmanaged resources (eg handles.) When the GC detects that an object is no longer in use, one of two things happens. Best case, if the object doesn't need to be finalized (it has no unmanaged resources or someone called suppress finalize) then it is cleaned up right then. Worst case, it gets put into another area for things that need to finalized, and lives longer (hanging on to those unmanaged resources longer) until eventually the finalizer runs and the object has been completely cleaned up.

Having a lot of objects that need finalizing can impact performance significantly. Disposing serves two purposes: it gives back the unmanaged resources, and it suppresses the finalizer (assuming you've implemented Dispose correctly) which gives the GC a break. Still, people might forget to call Dispose (or to use a Using) so the finalizer must exist. Just try not to rely on it.

Kate Gregory
+1  A: 

I wrote a blog post How to Implement IDisposable and Finalizers: 3 Easy Rules that describes in a fair amount of detail when and how to use each. I also have a few Q&As on the subject.

The infamous Microsoft documentation on how to implement IDisposable (and the corresponding FxCop rule) are horribly outdated. They do accurately describe how Microsoft implemented IDisposable... in .NET 1.0. When v2.0 came out, almost all classes in the BCL were retrofitted to follow guidelines similar to the ones described in my blog post (the only difference is that Microsoft does have the protected Dispose(bool) for classes designed for use as base classes). In particular, no BCL class to my knowledge is responsible for both managed and unmanaged resources.

Stephen Cleary