Inspired by my own experience with multithreaded Winforms applications, as well as questions such as
- Avoiding the woes of Invoke/BeginInvoke in cross-thread WinForm event handling?
- Avoid calling Invoke when the control is disposed
I've come up with a very simple pattern, whose soundness I would like to verify.
Basically I'm creating (and running throughout the application's lifetime) a BGW whose sole purpose is the synchronization of invoke requests. Consider:
public MainForm()
{
InitializeComponent();
InitInvocationSyncWorker();
}
private void InitInvocationSyncWorker()
{
InvocationSync_Worker.RunWorkerAsync();
}
private void InvocationSync_Worker_DoWork(object sender, DoWorkEventArgs e)
{
Thread.Sleep(Timeout.Infinite);
}
void InvokeViaSyncWorker(Action guiAction)
{
InvocationSync_Worker.ReportProgress(0, guiAction);
}
private void InvocationSync_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (IsDisposed) return; //we're in the GUI thread now, so no race condition right?
var action = (Action) e.UserState;
action();
}
public void SomeMethodCalledFromAnyThread() //Sample usage
{
InvokeViaSyncWorker(() => MyTextBox.Text = "Hello from another thread!"));
}
Granted, it's not the most economical of approaches (keeping a thread alive like that), but if it works and I haven't missed anything, it sure is the simplest I've seen.
Feedback is highly appreciated !