While discussing some code with a colleague, I ran across an unexpected behavior of GC.SuppressFinalize. I’ve put together a small sample for our discussion.
using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication1 { public class Base { ~Base() { Console.WriteLine(“Base Finalizer called”); } } public class Derived : Base { ~Derived() { Console.WriteLine(“Derived Finalizer called”); } public void Suppress() { GC.SuppressFinalize(this); } } class Program { static void Main(string[] args) { Derived d = new Derived(); d.Suppress(); Console.ReadLine(); } } }
Okay, so what gets printed out at the console?
Actually, nothing.
It was a little surprising to me at first, especially since after years of C++ programming the ~ immediately invokes destructor semantics in my head. I worked through a number of different variations, but I always got the same result. I used the !FinalizeQueue command available in the SOS extension of WinDBG to verify that there was only the Derived class reference on the queue. So when you say, SuppressFinalize(this) you really mean it!
Now, granted, this is a cheesy example. But the discussion came up when talking about the correct way to implement IDisposable. In the example provided, SuppressFinalize(this) is called in the Dispose method. Now that’s a good thing, because you want to prevent the call to the finalizer since you have already cleaned up any resources via your Dispose implementation. But, what happens if a class you derived from, either your own or a third party, does not implement IDisposable and instead is relying on the finalizer? Or they do implement IDisposable but somewhere else along the virtual method override chain someone forgot to call the base class implementation.
This really never should be a problem if your code implements the IDisposable interface correctly. And since implementing a Finalizer on your class has a negative performance impact you should only use them when you really need to. Anyway, this makes a great conversation at any nerd party
Post a Comment