I am working with a framework that runs its own event dispatcher in a separate thread. The framework may generate some events.
class SomeDataSource {
public event OnFrameworkEvent;
void FrameworkCallback() {
// This function runs on framework's thread.
if (OnFrameworkEvent != null)
OnFrameworkEvent(args);
}
}
I want to deliver these events to a Winforms object on Winforms thread. I obviously check for InvokeRequired
and dispatch it to Winforms thread if necessary.
class SomeForm : Form {
// ...
public void SomeAction(SomeArgs args) {
if (InvokeRequired) {
BeginInvoke(new Action(SomeAction), args);
return;
}
// ...
}
}
Now events may be delivered when the form is in the process of being closed, which causes all sorts of problems, so I unregister the form's event handler from framework's event source on Winforms thread like this:
var form = new SomeForm();
var src = new SomeDataSource();
// ...
src.OnFrameworkEvent += form.SomeAction;
form.Closing += (sender, eargs) => src.OnFrameworkEvent -= form.SomeAction;
Now, is this approach thread-safe? If the form is in the process of being closed, and a foreign thread calls BeginInvoke
, will the invocation still be queued for execution if the form is closed? (which means I still have a chance of encountering the same problem)
Is there a better approach or recommended pattern for cross-thread event handling?
No it is not. The thread might just be executing the event handler while you unregister it and close the form. Small odds, but not zero. You have to have the thread stopped before you can close the form. If you don't want to abort it, you'll have to keep the form open by canceling the FormClosing event, then let the thread's completion callback close the form.
Check this thread for more info.
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