使用backgroundworkers多线程处理GUI

时间:2015-06-10 11:44:48

标签: c# multithreading winforms user-interface

我的项目中有2名背景工作者:

BGW1:第一个工作人员用于从控制器读取数据并将数据转换为正确的格式

BGW2:第二个工作程序用于使用ReportProgress功能将转换后的数据和对象传递给GUI

整个过程需要尽可能实时,并且消息大约每0.5毫秒发送一次。当MainThread必须每5-10毫秒更新800点时,它会变得慌乱。

如果我以超过10fps的速度更新,这会导致GUI无响应。

我在网上找到的解决方案是这样的: Alternate Way of Multithreaded GUI

我已尝试通过设置

将此方法应用于我的后台工作人员
        // Prevent the framework from checking what thread the GUI is updated from.
        theMainForm.CheckForIllegalCrossThreadCalls = false;

在主要表格中。这允许我从一个单独的线程更新gui而不是主线程,从我理解。 在main中使用这一行应该意味着我可以从不是主线程的其他线程访问GUI元素,我不需要使用ReportProgress 更新图表,所以我尝试从 BGW2 DoWork部分更新图表。

更新工作于DoWork,但它似乎仍然只是将数据引用到MainThread,然后该线程更新图表,这会再次导致无法使用的GUI。

我是否必须完全摆脱背景工作者并且仅使用线程从链接的解决方案工作?或者是否有某种技巧可以让这种方法与后勤工作者合作。

3 个答案:

答案 0 :(得分:2)

好吧,不要经常更新。只需坚持固定的刷新率,并使用ConcurrentQueue传递读取数据的BackgroundWorker和呈现数据的GUI之间的数据点。一个简单的Timer应该足够好 - 每五秒钟,从ConcurrentQueue读取所有内容并更新图表。

不要从多个线程更新UI。这是支票存在的原因。

答案 1 :(得分:0)

你试过enforce the events being handled吗?这将清空事件队列,以便表单对用户负责。然而,正如Luaan所指出的那样,你最好以固定的速率更新GUI。

答案 2 :(得分:0)

一个背景工作者真的够了。

此操作的昂贵部分是;

  1. 同步回UI线程
  2. 在您执行此操作时阻止该工作人员。
  3. 解决性能问题,最小化#1。不要发布每个项目,每隔x毫秒发布许多项目。

    事实上,我建议根本不使用后台工作程序 - ReportProgress事件会阻止您的工作线程。