C# 退出时的后台工作人员问题

C# 退出时的后台工作人员问题,c#,multithreading,backgroundworker,C#,Multithreading,Backgroundworker,我在这里遇到了一个难题,我想知道一些事情: 我做错了吗 在不同的场景中,后台工作人员的预期行为是什么 如果可能的话,得到一个关于我为什么会有特殊行为的答案会很好 对于第1点,以及最后的第3点,我将解释我在伪代码中所做的工作,这样您就可以了解详细信息,而无需实际吐出数千行代码。在我写这篇文章时,我将查看代码本身,以确保信息在发生的时间和内容上是准确的。最后,我还将详细说明发生了什么以及为什么我会遇到问题 伪代码详细信息: 我有一个主UI线程(WinForms窗体),在选择一些配置选项后,单击一个按

我在这里遇到了一个难题,我想知道一些事情:

  • 我做错了吗
  • 在不同的场景中,后台工作人员的预期行为是什么
  • 如果可能的话,得到一个关于我为什么会有特殊行为的答案会很好
  • 对于第1点,以及最后的第3点,我将解释我在伪代码中所做的工作,这样您就可以了解详细信息,而无需实际吐出数千行代码。在我写这篇文章时,我将查看代码本身,以确保信息在发生的时间和内容上是准确的。最后,我还将详细说明发生了什么以及为什么我会遇到问题

    伪代码详细信息:

    我有一个主UI线程(WinForms窗体),在选择一些配置选项后,单击一个按钮

    此按钮的事件在内存和文件系统中执行一些初步设置工作,以使事情顺利进行,一旦完成,将触发一个后台工作人员。此backgroundworker初始化其他5个backgroundworker(表单范围变量),将其“完成”标志(bool-相同范围)设置为true,将其“日志”变量设置为新的
    列表(相同范围),完成后调用名为
    CheckEndConditions
    的方法。此方法调用在初始backgroundworker的
    DoWork()
    中完成,而不是在
    RunWorkerCompleted
    事件中完成

    CheckEndConditions
    方法执行以下逻辑:

  • 如果所有“完成”变量都设置为True
  • 抓取所有5个BW的“日志”变量,并将其内容添加到主日志中
  • 将所有5个BW的“日志”变量重置为新的
    列表
  • 将所有5个BW的“完成”变量重置为False
  • 调用
    MoveToNextStep()
  • 根据(5)的结果,获取需要处理的
    列表
  • 检查以确保(6)有要执行的操作
  • 如果否,请将所有“完成”标志设置为true,并调用自身移动到下一步
  • 如果是,请将此操作列表划分为5个列表,并将它们放入名为
    ThreadActionSets[]的
    list
    数组中
  • 检查每个分区列表的内容,如果没有,则将相应线程的“完成”标志设置为true(这确保没有“结束竞争场景”)
  • 使用
    RunWorkerAsync()
    启动所有5个线程(当然,除非我们已经完成了这一步)
  • 返回
  • 每个BW都有完全相同的
    DoWork()
    代码,基本上可以归结为以下几点:

  • 我有什么动作要执行吗
  • 如果否,请将my
    e.Result
    var设置为日志条目的空列表,然后退出
  • 如果是,循环集合中的每个动作并执行下面的4-5-6
  • 我在做什么样的行动?(组、模块等)
  • 根据(4),我在做什么类型的动作?(添加、删除、修改)
  • 根据(5),执行正确的操作并记录您在本地执行的所有操作
  • 完成所有操作后,将my
    e.Result
    var设置为“我所做的一切的日志”,然后退出
  • 每个BW都有相同的
    RunWorkerCompleted()
    代码,基本上可以归结为以下几点:

    试一试

  • e.Result
    var中,抓取
    列表
    ,并将其放入各自线程的“Log”var中
  • 将我各自的“完成”变量设置为true
  • 调用
    CheckEndConditions()
  • 抓住

  • 将我各自的“完成”变量设置为true
  • 调用
    CheckEndConditions()
  • 所以基本上就是这样。。。总之,我将大量操作拆分为5个分区,并将它们发送到5个线程,以比单个线程更快的速度执行它们

    问题

    我遇到的问题是,无论我在比赛场景(特别是终点场景)中投入了多少心思,我经常发现自己的程序被卡住了/没有响应

    一开始,我的代码设置效率低下,问题在于结束竞争场景,线程完成得太快,以至于最后一次调用
    CheckEndConditions
    时,看到其中一个“Done”变量仍然设置为false,而实际上它并没有/它已经完成。。。所以我把我的代码改成了你在上面看到的代码,我认为它可以解决这个问题,但它没有。整个进程仍然处于阻塞/休眠状态,当这种情况发生时,实际上没有线程运行任何处理,这意味着上次调用
    CheckEndConditions
    时出现了一些错误(我想,不确定)

    所以我的第一个问题是:我做错了吗?做我想做的事情的标准方式是什么?对我来说,我所做的事情的逻辑是合理的,但它并没有表现出我所期望的那样,所以也许逻辑是不合理的

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

    第三个问题:有人看到我的问题发生的明显原因吗


    谢谢你的帮助

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

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


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

    调试时它挂起在哪里?(您可以暂停调试以准确查看哪个线程在哪里)就是这样。。。我有代码在UI运行时更新它,所以我等待UI停止更新/停留在某个位置一段时间,所以我暂停调试器,我得到Done1、2、3、4、5都设置为True,但什么都没有发生。。。几乎