SynchronizationContext.Post 在BackgroundWorker 内不起作用

发布于 2024-12-22 13:34:03 字数 3689 浏览 2 评论 0原文

我正在使用后台工作者来完成所有处理。在里面,我有很多地方可以写入“日志”文本框。所有这些都工作得很好,但在后台工作程序的最后,即最后一行,我通过 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

许一世地老天荒 2024-12-29 13:34:03
MessageBox.Show("It made it...");

也可能会引起问题。因为这是期待 UI 线程,而实际上,您在后台线程上

MessageBox.Show("It made it...");

may also be causing problems. as this is expecting the UI thread, when in fact, your on a background thread

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文