退出后的BackgroundWorker问题

时间:2014-07-29 17:08:06

标签: c# multithreading backgroundworker

我在这里遇到一些难题,想知道几件事:

  1. 我这样做错了吗?
  2. 背景工作者在不同场景中的预期行为是什么......
  3. 如果可能,请回答一下为什么我会得到具体的行为会很好......
  4. 对于第1点,最终也是3,我将解释我在伪代码中所做的事情,这样你就可以获得详细信息而不会真正吐出数千行代码。当我写这篇文章时,我将查看代码本身,以确保信息准确无论何时何地发生。在最后,我还将详细说明正在发生的事情以及我遇到问题的原因。

    伪代码详细信息:

    我有一个主UI线程(WinForms表单),在选择一些配置选项后,您可以单击一个按钮。

    此按钮的事件会在内存和文件系统中执行一些初步设置工作,以便完成工作,一旦完成,就会触发一个后台工作人员。这个背景工作者初始化了5个其他背景工作者(形成范围变量),设置他们的&#34;完成&#34; flags(bool - 相同范围)为true,设置&#34; Log&#34; vars到新的List<LogEntry>(相同的范围),一旦完成,就会调用名为CheckEndConditions的方法。此方法调用在初始后台工作程序的DoWork()内完成,而不是在RunWorkerCompleted事件中完成。

    CheckEndConditions方法执行以下逻辑:

    1. 如果所有&#34;完成&#34; vars设置为True ...
    2. 抓住&#34; Log&#34;所有5个BW的变量,并将其内容添加到主日志中。
    3. 重置&#34; Log&#34;所有5个BW的变量到新的List<LogEntry>
    4. 重置&#34;完成&#34;所有5个BW的变量为假。
    5. 调用MoveToNextStep()方法,该方法返回代表下一步执行的Enum
    6. 根据(5)的结果,抓住需要处理的List<ActionFileAction>
    7. 检查以确保(6)有执行的操作
    8. 如果否,请设置ALL&#34;完成&#34; flags为true,并调用自己移动到下一步...
    9. 如果是,请将此操作列表分为5个列表,并将它们放在List<ActionFileAction> ThreadActionSets[]
    10. 的数组中
    11. 检查每个分区列表中的内容,如果没有,则设置&#34;完成&#34;将相应线程的标志设置为true(这确保没有&#34;结束竞赛方案&#34;)
    12. 使用RunWorkerAsync()关闭所有5个主题(除非我们当前处于完成步骤)
    13. Return
    14. 每个BW都具有完全相同的DoWork()代码,基本上归结为以下内容:

      1. 我有任何行动要做吗?
      2. 如果否,请将我的e.Result var设置为空的日志条目列表并退出。
      3. 如果是,则循环播放集合中的每个动作并执行以下4-5-6 ......
      4. 我在做什么行动? (组,模块等)
      5. 根据(4),我在做什么类型的行动? (添加,删除,修改)
      6. 基于(5),执行正确的操作并记录您在本地执行的所有操作
      7. 完成所有操作后,将我的e.Result var设置为&#34;记录我已完成的所有内容&#34;,然后退出。
      8. 每个BW都有相同的RunWorkerCompleted()代码,基本归结为以下内容:

        TRY

        1. e.Result var中,抓住List<LogEntry>并将其放入我自己的主题&#34; Log&#34;变种
        2. 设置我自己的&#34;完成&#34; var为true
        3. 致电CheckEndConditions()
        4. CATCH

          1. 设置我自己的&#34;完成&#34; var为true
          2. 致电CheckEndConditions()
          3. 所以这基本上就是......总而言之,我将大量的动作分成5个分区,然后将它们发送到5个线程,以比单个线程更快的速度执行它们。

            问题

            我遇到的问题是,我经常发现自己,无论我为种族场景(特别是最终版本)投入了多少想法,都有一个卡住/无响应的程序。

            一开始,我设置的代码效率低下,而问题出现在End Race Scenarios中,并且线程完成得如此之快以至于最后一次调用CheckEndConditions看到了其中一个&#34; Done&#34 ; vars仍然设置为false,而事实上它并没有完成......所以我把我的代码改为你上面看到的,我想,这会解决问题,但它没有。整个过程仍然陷入困境/睡着,当发生这种情况时,没有线程实际运行任何处理,这意味着最后一次调用CheckEndConditions时出现了问题(我认为,不确定)。

            所以我的第一个问题:我做错了吗?做我想做的事情的标准方法是什么?我所做的事情的逻辑对我来说听起来很合理,但它并没有表现出我对它的期望,所以逻辑听起来可能并不合适? ...

            第二个问题:当出现这种情况时,BW的预期行为是什么: DoWork()方法中未捕获的错误...是否会触发RunWorkerCompleted()事件?如果没有,会发生什么?

            第3个问题:有没有人看到我的问题出现的明显原因?

            感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

根据OP的要求将我的评论作为答案重新发布:

RunWorkerCompleted事件不一定会在创建它的同一个线程上引发(除非它是在UI线程上创建的)请参阅BackgroundWorker RunWorkerCompleted Event

有关详细信息,请参阅OP注释。