で長いタスクを実行しておりBackgroundWorker
、 を介して UI を更新していReportProgress
ます。ただし、プロセスの途中で、データを取得するために COM 呼び出しを行う必要があり、UI スレッドで行う必要があると思います。Control.Invoke を介してこれを実行してみました。しかし、私はデッドロックを取得しています。(with )Control.Invoke
で使用できませんか?BackgroundWorker
ShowDialog
コードを単純化しようとしました:
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;
}
編集:
例外はありません。UI は更新され続けますが、進行が停止します。Break All は、Control.Invoke 呼び出しでワーカー スレッドを表示し、ShowDialog 呼び出しで GUI スレッドを表示します。
GUI スレッドがメッセージ ループにあるようです。
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext コンテキスト) + 0x65 バイト
それがUIが更新され続ける理由だと思います。BackgroundWorker 内にロックはありますか?