I am relatively new to WPF, and some things with it are quite foreign to me. For one, unlike Windows Forms, the WPF control hierarchy does not support IDisposable. In Windows Forms, if a user control used any managed resources, it was very easy to clean up the resources by overriding the Dispose method that every control implemented.
In WPF, the story is not that simple. I have searched for this for several hours, and encountered two basic themes:
The first theme is Microsoft clearly stating that WPF does not implement IDisposable because the WPF controls have no unmanaged resources. While that may be true, they seem to have completely missed the fact that user extensions to their WPF class hierarchy may indeed use managed resources (directly or indirectly through a model). By not implementing IDisposable, Microsoft has effectively removed the only guaranteed mechanism by which unmanaged resources used by a custom WPF control or window can be cleaned up.
Second, I found a few references to Dispatcher.ShutdownStarted. I have tried to use the ShutdownStarted event, but it does not seem to fire for every control. I have a bunch of WPF UserControl's that I have implemented a handler for ShutdownStarted, and it never gets called. I am not sure if it only works for Windows, or perhaps the WPF App class. However it is not properly firing, and I am leaking open PerformanceCounter objects every time the app closes.
Is there a better alternative to cleaning up unmanaged resources than the Dispatcher.ShutdownStarted event? Is there some trick to implementing IDisposable such that Dispose will be called? I would much prefer to avoid using a finalizer if at all possible.
I'm afraid that Dispatcher.ShutdownStarted really does seem to be the only mechanism WPF provides for disposing of resources in UserControls. (See a very similar question I asked a while ago).
Another way to approach the problem is to move all of your disposable resources (if at all possible) out of the code behind and into separate classes (such as the ViewModel when using the MVVM pattern). Then at a higher level you could handle your main window closing and notify all the ViewModels via a Messenger class.
I am surprised you don't get the Dispatcher.ShutdownStarted event. Are your UserControls attached to the top-level window at the time?