« “Memory leak” with BitmapImage and MemoryStream | Main | Exception 0xc0020001 in C++/CLI assembly »
April 8, 2008
Finalizers called from partially constructed objects
Did you know that finalizers are called from partially constructed objects? I certainly didn't. If an exception is thrown from a class constructor, that object is considered “partially constructed” – and its finalizer is still run when the object is garbage collected. Chris Brumme mentioned this four years ago when he helped us understand that it’s hard to implement Finalize properly: “Your Finalize method must tolerate partially constructed instances.”
A coworker discovered this fact when he was unit testing a class that called Debug.Fail in its finalizer to make sure that its instances were being disposed properly. He passed an invalid argument to the constructor to verify that an exception would be thrown – but then found that the call to Debug.Fail in the finalizer was causing tests to fail.
We couldn't figure out a good way to determine whether an object is partially constructed, so we just had to hack around the problem. Any better ideas for detecting undisposed objects?
Posted by Ed Ball at April 8, 2008 3:49 PM
Trackback Pings
TrackBack URL for this entry:
http://blog.logos.com/mt-cgi/mt-tb.cgi/206
Comments
It seems to me that the real problem you're facing is your inability to control the Debug.Fail method. My first instinct would be a way to turn that off in the unit testing, so you can further isolate the SUT.
I've always hated having to deal with the Trace/Debug classes when unit testing. I've gone as far, on my current project, to create a "Check" class, which I can manipulate at will. So, you could have
[Test]
public void TestSomethingThatMayCallFinalizer()
{
Check.TurnAllNotificationsOff();
try {
new ClassWithTheFinalizaer("invalid data");
}
finally {
Check.TurnNotificationsBackOn();
}
}
The problem here, without injecting a check object into the class that nobody else uses, you're dealing with a Shared Fixture and could affect other tests in the process. If you haven't read XUnit Test Patterns (http://xunitpatterns.com), it is a great reference for this.
Posted by: Michael Hedgpeth at April 8, 2008 6:50 PM