4 ms·
I think this is pretty much the reason most people think is a good reason to use a finalizer, but it's also the case that inevitably comes back to bite you. I'
by copsarebastards 11y ago
I think this is pretty much the reason most people think is a good reason to use a finalizer, but it's also the case that inevitably comes back to bite you.
I've made this mistake, and the way it bit me was in a system where I was spinning up and disposing a lot of event subscriptions. My UI slowed to a crawl. It turned out that the finalizer queue is pretty low priority, so event subscriptions weren’t getting disposed by the finalizer until there was time to do so. As a result, extra event handlers were being notified (and doing nothing because they in turn called other events which were no longer subscribed). This wouldn’t have been a problem to find and fix, except that I had written the finalizer six months before and one of our junior devs had written code that depended on Dispose() being called by the finalizer instead of explicitly. The result was that profiling showed a lot of time being spent on meaningless code that wasn’t actually related to the problem. It took almost a week to figure out the issue. I thought when I was writing that finalizer that I was writing fail-safe code, but in reality I had just made the failure harder to trace.
In short, the way to ensure that Dispose() has been called is to call Dispose() at the appropriate time. There’s no shortcut, you have to just manage the lifetime of your objects correctly.
- StillBored 11y agoI wasn't suggesting calling the dispose method in the finalizer (that is evil), rather setting a flag in the dispose method that indicates whether it was called. Then logging a message/whatever in the finalizer if that flag isn't set. AKA, using it as a debugging aid.