Today I was asked by a colleague about some of my blog posts yesterday regarding IDisposable and Finalize. So here’s the first post in a series of Q&A regarding finalizers. Enjoy!
Question: Does GC.SuppressFinalize(this) work if the object is not already on the finalize queue?
Answer: Yes, it does.
There’s some confusion on what exactly GC.SuppressFinalize does, because the .NET 1.1 docs state “The method removes obj from the set of objects that require finalization.” However, since .NET 2.0, the docs have been updated to read “This method sets a bit in the object header, which the system checks when calling finalizers.” This clarifies GC.SuppressFinalize semantics nicely.
Because of the old docs, there is some FUD regarding GC.SuppressFinalize floating around in old forum and newsgroup posts. Some people insist that it must be the last thing done by a Dispose() implementation. However, the truth is that it is safe to call at any time. In fact, some BCL classes even call GC.SuppressFinalize in their constructors!
There is an argument that can be made for calling GC.SuppressFinalize as the last statement in a Dispose method: it ensures that the finalizer is only suppressed if Dispose does not throw. However, it is very poor practice to have a Dispose method that throws, so this argument has little merit.
Output of Test Code:
Test object is still alive! Returning from Main