I'm running a long task in a BackgroundWorker
, updating the UI via ReportProgress
. However, in the middle of the process, I need to make a COM-call to get some data, and I think I need to do it on the UI thread. I tried doing this via Control.Invoke. However, I'm getting a deadlock. Can't one use Control.Invoke
in a BackgroundWorker
(with ShowDialog
)?
I've tried to simplify the code:
var log = new LogWindowForm();
worker.DoWork += (sender, args) =>
{
creator.LogProgress = (s, i) => worker.ReportProgress(i,s);
creator.GetMoreDataFunc = (s) => InvokeGetMoreDataOnGuiThread(log, s);
...
var data = GetMoreDataFunc("id:"+id)
};
worker.RunWorkerAsync();
log.ShowDialog();
private Dictionary<string, string> InvokeGetMoreDataOnGuiThread(Control invokeControl, string id)
{
var data = new Dictionary<string, string>();
Action action = () => data = GetMoreDataFromComObject(mainComObject, id);
invokeControl.Invoke(action); // deadlock!
return data;
}
Edit:
There are no exceptions, the UI keeps updating but it stops progressing. Break All shows the worker thread in the Control.Invoke call and the GUI thread somewhere in the ShowDialog call.
The GUI thread seems to be in the message loop:
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x65 bytes
I guess that's why the UI keeps updating. Is there some locking inside the BackgroundWorker?