SynchronizationContext.Post 在BackgroundWorker 内不起作用
我正在使用后台工作者来完成所有处理。在里面,我有很多地方可以写入“日志”文本框。所有这些都工作得很好,但在后台工作程序的最后,即最后一行,我通过 SynchronizationContext
进行的又一个调用没有触发。为什么所有其他调用都有效,而最后一个调用却不起作用?
我应该补充一点,应用程序只是“挂起”,甚至有一个 EventLog 条目显示:
The program MVST.CodeSync.exe version 2.0.0.0 stopped interacting with Windows and was closed. To see if more information about the problem is available, check the problem history in the Action Center control panel. Process ID: 1f5c Start Time: 01ccc0e2e7ca1d42 Termination Time: 16 Application Path: C:\Users\ganders\Desktop\NewCodeSync\MVST.CodeSync.exe Report Id: 629f3533-2cd6-11e1-9e15-005056b75254
这是 DoWork
方法(在调用 RunWorkerAsync
时执行):
private void bgw_StartCompare(object sender, DoWorkEventArgs e)
{
OnWriteLogArgs args = null;
CompareData compareData = e.Argument as CompareData;
// We need to iterate through all of the nodes and if they are checked, continue
foreach (TreeNode subSystemNode in compareData.TreeNodes)
{
if (!subSystemNode.Checked)
continue;
args = new OnWriteLogArgs(String.Format("-------------------------- Comparing sub-system: \"{0}\" with CompareType: \"{1}\" --------------------------", subSystemNode.Text, compareData.CompareType));
syncContext.Post(delegate { OnWriteLog(args); }, null);
// Each of these nodes should be a server, so continue
foreach (TreeNode serverNode in subSystemNode.Nodes)
{
if (!serverNode.Checked)
continue;
args = new OnWriteLogArgs(String.Format("-------------------------- Comparing server: \"{0}\" with CompareType: \"{1}\" --------------------------", serverNode.Text, compareData.CompareType));
syncContext.Post(delegate { OnWriteLog(args); }, null);
// The "tag" contains the server information that we need to do the comparison
CustomConfig.Server server = (CustomConfig.Server)serverNode.Tag;
if (!compareData.DoneInitialCompare)
CompareAll(compareData, server, string.Empty, server.CompareBasePath, serverNode, compareData.CompareType);
else
CompareAllByTreeNode(compareData, server, serverNode, compareData.CompareType);
}
}
syncContext.Post(delegate { OnWriteLog(new OnWriteLogArgs("Finished the compare...")); }, null);
RebuildTreeViewArgs rArgs = new RebuildTreeViewArgs(compareData.OnlyShowDifferences, compareData.TreeNodes);
syncContext.Post(delegate { OnRebuildTreeView(rArgs); }, null);
MessageBox.Show("It made it...");
syncContext.Post(delegate { OnWriteLog(new OnWriteLogArgs("Finished calling the rebuild tree view method...")); }, null);
}
您会注意到在 foreach 循环结束时,我写的内容是“完成比较...”,确实会写,但下一个同步调用:
syncContext.Post(delegate { OnRebuildTreeView(rArgs); }, null);
永远不会被执行。这是该方法:
private void OnRebuildTreeView(RebuildTreeViewArgs args)
{
syncContext.Post(delegate { OnWriteLog(new OnWriteLogArgs("Made it to the OnRebuildTreeView method...")); }, null);
while (bgw.IsBusy)
{
syncContext.Post(delegate { OnWriteLog(new OnWriteLogArgs("Sleeping...")); }, null);
Thread.Sleep(1000);
}
syncContext.Post(delegate { OnWriteLog(new OnWriteLogArgs("Starting the rebuild of the TreeView...")); }, null);
TreeNode[] tn = args.NewStructure;
tvSync.Nodes.Clear();
foreach (TreeNode node in tn)
tvSync.Nodes.Add(node);
foreach (TreeNode node in tvSync.Nodes)
FixCheckedAndUnCheckedNodes(node);
ReloadTreeView(args.OnlyShowDifferences);
}
I'm using a background-worker to do all of my processing. Inside there, I have many places where I write to my "log" text box. All of those work great, but at the end of the background-worker, the very last line, I have one more call via SynchronizationContext
that doesn't fire. Why do all of the other calls work, and not the last one?
I should add that the application just "hangs", and there's even an EventLog entry saying:
The program MVST.CodeSync.exe version 2.0.0.0 stopped interacting with Windows and was closed. To see if more information about the problem is available, check the problem history in the Action Center control panel. Process ID: 1f5c Start Time: 01ccc0e2e7ca1d42 Termination Time: 16 Application Path: C:\Users\ganders\Desktop\NewCodeSync\MVST.CodeSync.exe Report Id: 629f3533-2cd6-11e1-9e15-005056b75254
Here's the DoWork
method (which is executed when calling RunWorkerAsync
):
private void bgw_StartCompare(object sender, DoWorkEventArgs e)
{
OnWriteLogArgs args = null;
CompareData compareData = e.Argument as CompareData;
// We need to iterate through all of the nodes and if they are checked, continue
foreach (TreeNode subSystemNode in compareData.TreeNodes)
{
if (!subSystemNode.Checked)
continue;
args = new OnWriteLogArgs(String.Format("-------------------------- Comparing sub-system: \"{0}\" with CompareType: \"{1}\" --------------------------", subSystemNode.Text, compareData.CompareType));
syncContext.Post(delegate { OnWriteLog(args); }, null);
// Each of these nodes should be a server, so continue
foreach (TreeNode serverNode in subSystemNode.Nodes)
{
if (!serverNode.Checked)
continue;
args = new OnWriteLogArgs(String.Format("-------------------------- Comparing server: \"{0}\" with CompareType: \"{1}\" --------------------------", serverNode.Text, compareData.CompareType));
syncContext.Post(delegate { OnWriteLog(args); }, null);
// The "tag" contains the server information that we need to do the comparison
CustomConfig.Server server = (CustomConfig.Server)serverNode.Tag;
if (!compareData.DoneInitialCompare)
CompareAll(compareData, server, string.Empty, server.CompareBasePath, serverNode, compareData.CompareType);
else
CompareAllByTreeNode(compareData, server, serverNode, compareData.CompareType);
}
}
syncContext.Post(delegate { OnWriteLog(new OnWriteLogArgs("Finished the compare...")); }, null);
RebuildTreeViewArgs rArgs = new RebuildTreeViewArgs(compareData.OnlyShowDifferences, compareData.TreeNodes);
syncContext.Post(delegate { OnRebuildTreeView(rArgs); }, null);
MessageBox.Show("It made it...");
syncContext.Post(delegate { OnWriteLog(new OnWriteLogArgs("Finished calling the rebuild tree view method...")); }, null);
}
You'll notice at the end of the foreach
loop, I do my write that says Finished the compare...
, and that DOES write, but the next sync call:
syncContext.Post(delegate { OnRebuildTreeView(rArgs); }, null);
Never gets executed. Here's that method:
private void OnRebuildTreeView(RebuildTreeViewArgs args)
{
syncContext.Post(delegate { OnWriteLog(new OnWriteLogArgs("Made it to the OnRebuildTreeView method...")); }, null);
while (bgw.IsBusy)
{
syncContext.Post(delegate { OnWriteLog(new OnWriteLogArgs("Sleeping...")); }, null);
Thread.Sleep(1000);
}
syncContext.Post(delegate { OnWriteLog(new OnWriteLogArgs("Starting the rebuild of the TreeView...")); }, null);
TreeNode[] tn = args.NewStructure;
tvSync.Nodes.Clear();
foreach (TreeNode node in tn)
tvSync.Nodes.Add(node);
foreach (TreeNode node in tvSync.Nodes)
FixCheckedAndUnCheckedNodes(node);
ReloadTreeView(args.OnlyShowDifferences);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
也可能会引起问题。因为这是期待 UI 线程,而实际上,您在后台线程上
may also be causing problems. as this is expecting the UI thread, when in fact, your on a background thread