使用后台工作线程对 GUI 进行多线程处理

本文关键字:GUI 多线程处理 线程 后台 工作 | 更新日期: 2023-09-27 17:55:17

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

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

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

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

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

我在网上找到的一个解决方案是这样的:多线程 GUI 的替代方法

我试图通过设置

        // Prevent the framework from checking what thread the GUI is updated from.
        theMainForm.CheckForIllegalCrossThreadCalls = false;

在主窗体中。据我所知,这允许我从单独的线程而不是主线程更新 gui。在 main 中使用这一行应该意味着我可以从不是主线程的其他线程访问 GUI 元素,并且我不需要使用ReportProgress以更新图表,所以我尝试从 BGW2DoWork部分更新图表。

更新从 DoWork 开始工作,但它似乎仍然只是将数据引用到 MainThread,然后该线程更新图表,这导致 GUI 再次不可用。

我是否必须完全摆脱后台工作者,并且只使用线程从链接到工作的解决方案?或者是否有某种技巧可以让这种方法与后台工作者一起工作。

使用后台工作线程对 GUI 进行多线程处理

好吧

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

不要从多个线程更新 UI。检查在那里是有原因的。

一个后台工作者真的就足够了。

此操作的昂贵部分是;

  1. 同步回 UI 线程
  2. 在您执行此操作时阻止工作人员。

解决性能问题,最小化#1。不要发布每个项目,每x毫秒发布许多项目。

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

您是否尝试强制执行正在处理的事件?这将清空事件队列,以便表单对用户负责。尽管如此,您最好以固定速率更新 GUI,正如 Luaan 所指出的那样。