【问题标题】:BackgroundWorker might be causing my application to hangBackgroundWorker 可能导致我的应用程序挂起
【发布时间】:2023-03-19 06:21:01
【问题描述】:

我有一个使用 BackgroundWorker 执行一系列测试的表单。我使用 ProgressChanged 事件将消息发送到主线程,然后主线程执行 UI 上的所有更新。我已经梳理了我的代码,以确保我没有对后台工作人员中的 UI 做任何事情。我的代码中没有 while 循环,BackgroundWorker 的执行时间有限(以秒或分钟为单位)。但是,由于某种原因,当我锁定我的计算机时,当我重新登录时,应用程序经常会挂起。问题是,发生这种情况时,BackgroundWorker 甚至都没有运行。我认为它与 BackgroundWorker 相关的原因是因为表单仅在加载应用程序后执行 BackgroundWorker 时挂起(它仅在给定特定用户输入时运行)。

我通过 RunWorkerAsync 方法从 UI 中的 TreeView 向该线程传递了一个 TreeNode 列表,但我只在工作线程中读取这些节点。我对它们所做的任何修改都是通过 progressChanged 事件在 UI 线程中完成的.

我确实在我的工作线程中使用 Thread.Sleep 以定时间隔执行测试(这涉及通过 TCP 套接字发送消息,这不是在工作线程中创建的)。

我完全不明白为什么我的应用程序可能会挂起。我确定我在某处做“非法”的事情,我只是不知道是什么。

【问题讨论】:

  • 要缩小问题范围,注释掉 ProgressChanged 处理程序并查看它是否仍然锁定。如果它仍然锁定,则继续注释掉部分直到它起作用。
  • 技术上,您也不应该从 BGW 中的 UI 对象中读取数据。我建议使用 LINQ 将 IEnumerable<string>(或您需要的任何数据,如果不是 string)传递给 BGW 线程。
  • 问题是锁定不容易重现。有时它可能几个小时都不会发生,因此可能需要几天时间才能缩小范围。使用 LINQ 将 TreeNode 列表传递给我的线程而不是作为 RunWorkerAsync 的参数有什么好处?

标签: c# forms backgroundworker freeze


【解决方案1】:

我通过 RunWorkerAsync 方法从 UI 中的 TreeView 向该线程传递了一个 TreeNode 列表,但我只在工作线程中读取这些节点。

“仅读取”我假设您的意思是“仅访问属性获取器”。但是属性 getter 可以执行您无法控制的代码 - 例如 TreeNode.IsSelected 将调用本机方法并发送 Windows 消息(使用 Reflector 查看)。

相反,您应该从 UI 线程中的 TreeView 中提取您需要的数据并将其传递给后台工作人员。您不仅可以避免这个问题,而且您的设计也会更加松散耦合。

【讨论】:

  • 我已经扩展了 TreeNode 类,以便将一堆数据添加到我需要使用的节点中。将这些数据提取到数据结构中并传递它会做很多工作。如果我只是将 TreeNode 传递给 BGW,然后在 BGW 中创建每个节点的副本,然后再访问它们的任何数据会怎样?
  • 我会说咬紧牙关。从后台工作人员访问 UI 元素会导致未定义的行为。即使您以某种方式使其正常工作,这也将是一场维护噩梦。
  • 如果我只访问我自己知道没有任何特殊调用的类的属性怎么办?如果我需要“IsChecked”属性,我可以创建自己的并设置它,然后再将其交给 BGW。
【解决方案2】:

嗯,这个很旧,但事实证明这个问题与我的代码完全无关。由于最近我们的软件发生了变化,日志记录的数量呈指数增长,我们的日志缓冲区溢出导致应用程序崩溃。这只是一个巧合,这发生在我处理这段特定代码的同时。无论如何,我仍然确保我没有对 BackgroundWorker 中的 UI 元素进行任何操作,即使它与选中/取消选中 TreeNode 一样微不足道。

【讨论】:

    【解决方案3】:

    听起来像可怕的UserPreferenceChanged 事件问题,在没有消息泵的情况下在后台线程上创建了 ui 组件。主ui线程同步向所有注册的ui窗口发送事件,由于后台工作线程上的ui组件无法处理UserPreferenceChanged事件,会挂起。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多