In .NET, under which circumstances should I use GC.SuppressFinalize()?
What advantage(s) does using this method give me?
In .NET, under which circumstances should I use GC.SuppressFinalize()?
What advantage(s) does using this method give me?
That method must be called on the Dispose method of objects that implements the IDisposable, in this way the GC wouldn't call the finalizer another time if someones calls the Dispose method.
See: http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx
you're telling the system that whatever work would have been done in the finalizer has already been done, so the finalizer doesn't need to be called. From the .NET docs:
Objects that implement the IDisposable interface can call this method from the IDisposable.Dispose method to prevent the garbage collector from calling Object.Finalize on an object that does not require it.
In general, most any Dispose() method should be able to call GC.SupressFinalize(), because it should clean up everything that would be cleand up in the finalizer.
SupressFinalize is just something that provides an optimization that allows the system to not bother queing the object to the finalizer thread. A properly written Dispose()/finalizer should work properly with or without a call to GC.SupressFinalize().
Generally when implementing the IDisposable pattern when you do not need to finalize your object. Check out http://www.blackwasp.co.uk/IDisposable.aspx for examples.
SuppresFinalize should only be called by a class that has a finalizer. It's informing the GC that this
object was cleaned up fully.
The recommended IDisposable pattern when you have a finalizer is....
public class MyClass : IDisposable
{
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// called via myClass.Dispose().
// OK to use any private object references
}
disposed = true;
}
}
public void Dispose() // Implement IDisposable
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MyClass() // the finalizer
{
Dispose(false);
}
}
Normally, the CLR keeps tabs on objects with a finalizer when they are created (making them more expensive to create). SuppressFinalize tells the garbage collector (GC) that the object was cleaned up properly and doesn't need to go onto the the finalizer queue. It looks like a C++ destructor, but it doesn't act anything like one.
The SuppressFinalize optimization is not trivial, as your objects can live a long time waiting on the finalizer queue. Don't be tempted to call SuppressFinalize on other objects mind you. That's a serious defect waiting to happen.
Design guidelines inform us that a finalizer isn't necessary if your object implements IDisposable, but if you have a finalizer you should implement IDisposable to allow deterministic cleanup of your class.
Most of the time you should be able to get away with IDisposable to clean up resources. You should only need a finalizer when your object holds onto unmanaged resources and you need to guarantee those resources are cleaned up.
Note: Sometimes coders will add a finalizer to debug builds of their own IDisposable classes in order to test that code has disposed their IDisposable object properly.
public void Dispose() // Implement IDisposable
{
Dispose(true);
#if DEBUG
GC.SuppressFinalize(this);
#endif
}
#if DEBUG
~MyClass() // the finalizer
{
Dispose(false);
}
#endif