Don’t cleanup managed resources in destructors!
X DO NOT access any finalizable objects in the finalizer code path, because there is significant risk that they will have already been finalized
When garbage collection kicks in and finalizers are being called there is no guarantee as to what order they will be called in. That means if you have ObjectA composed of ObjectB you cannot know which will have its destructor called first. Meaning if you attempt to clean up ObjectB in ObjectA’s destructor you will be in for the surprise you just saw above, it may be possible that ObjectB was already finalized. There you have it, something that can go terrible wrong when you clean up managed resources in a destructor and it can be very tricky to track this down when it intermittently plays with your mind.
Properly implement the dispose pattern and you will not run into this problem.
Do consider avoiding making any object finalizable in the first place.
In .NET 4.0 if one makes use of the TPL Tasks and does not handle exceptions potentially thrown by the task(s) then when the Garbage Collector runs it would throw the AggregateException for you on the finalization thread and behave as would on any other unhandled exception. The catch however being that the AggregateException needs to be flattened to get more detail out of it which will not be done for you.
In .NET 4.5+ this was changed, now any unhandled exceptions will become… well unhandled and will be silent. This is not very ideal because a lot can go wrong and you will never find out at all. In your app.config you are however able to enable this behavior as follows:
You do not really have to enable this behavior. In fact they probably removed that by default for a reason. Instead you need to handle the exceptions properly and flatten the AggregateException. This I will cover in a separate post as there are multiple interesting ways to achieve this..