I have a subclass of System::Windows::Forms::UserControl which allocates some unmanaged resources which have to be released in the destructor. It is used in WPF application through WindowsFormsHost. If the control is shown at least once in the application it’s destructor will be called. But if the instance of the control is created but never shown only finalizer gets called.
Why does that happen?
Calling IDisposable::Dispose() invokes your ~destructor. It is an optional call, it must be made explicitly by other code. You’ll get it when you add your control to the Controls collection of a container (like a Form or Panel) and the container gets properly disposed. Which in general is automatic when the user closes a window by clicking the close button.
Lots of scenarios where that “automatic” doesn’t work. The notorious ones is when you remove a control yourself by calling the Controls::Remove/At() or the Controls::Clear() method. It certainly won’t be automatic when you just used gcnew to create the instance but then never actually made it visible by adding it to a container control. The ControlsCollection class can’t do its job.
The optional call needs to be backed up by the guaranteed call. You must always implement the !finalizer when unmanaged resources need to be released. So they can never be leaked when the code that uses your control skips the optional call, for whatever reason. That !finalizer will be called, just later.