I have some code in a WPF application that looks like this:
public class MyTextBox : System.Windows.Controls.TextBox, IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
Dispatcher.BeginInvoke((Action) delegate
{
// do work on member variables on the UI thread.
});
}
~MyTextBox()
{
Dispose(false);
}
}
The dispose method is never getting explicitly called so the destructor calls it. It seems like in this case the object would be destroyed before the delegate in the BeginInvoke fires on the UI thread. It appears to be working though. What is happening here? Is this safe?
It seems like in this case the object would be destroyed before the delegate in the BeginInvoke fires on the UI thread
The finalizer queues work to the UI message loop. The object may finish running its finalizer method before the actual delegate gets invoked on the UI thread, but that doesn't matter, as the delegate gets queued regardless.
What is happening here?
You're queueing work to the UI from the finalizer.
Is this safe?
Safe is a broad term. Would I do this? Definitely not. It looks and feels weird that you're invoking manipulation of UI elements from a finalizer, especially given this is a TextBox
control. I suggest you get the full grasp of what running a finalizer guarantees and doesn't guarantee. For one, running a finalizer doesn't mean the object gets cleaned up in memory right away.
I'd also suggest reading @EricLippert posts: Why everything you know is wrong, Part1 & Part2
When you call BeginInvoke
you're adding a delegate to a queue in the dispatcher, and that delegate is going to be pointing to an object that has a reference to the object that Dispose
was called on. Since there is a reference to the object accessible through a rooted variable, this object is not eligible for collection.
Now, this is going to be extremely confusing to others using this code, so you should try to avoid "reanimating" objects that have already been finalized if at all possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With