Share via


In God We Trust, Everybody Else Must Bring Data

One day, I was presented with a problem, that the finalizer was not called during application pool recycle. I was busy, so I did not have chance to respond. Later on, I checked the code, it was modified to inherit from CriticalFinalizerObject class, and a comment saying that even though the class is inherited from CriticalFinalizerObject, the finalizer sometimes is not getting called. There was a logic in the finalizer that is often not got executed, the assumption was, the finalizer sometime was not called.

After digging the code, I discovered what was going on, above the logic that often not get executed, there was one line of code that close a FileStream object that is also a field of this class.

Managed code does not guarantee the order of the objects that are being garbage-collected, the finalizer may have accessed the garbage-collected objects. The code below the code that closes the FileStream object did not get executed if the FileStream has been garbage-collected.

It does not matter whether the class is inherited from CriticalFinalizerObject or not, the exception will give the impression that the finalizer was not called.

A quick look on ASP.Net Event Log shows ObjectDisposed exception whenever the logic is not called, a simple logging showed that the finalizer was always called. After isolating the issue, the fix is much simpler and guaranteed to work all the time.

Next time you hear about a problem, ask for data, profiler, repro steps. Just like a Test Manager that I knew said, ‘In God we trust, everybody else must bring data’.