multithreading - 如何从另一个线程访问UI控件?

标签 multithreading winapi

我知道,为了从另一个线程访问UI控件,我应该使用PostMessage()。但是,PostMessage()是异步的,因此例如,如果我尝试更改"EDIT"控件的文本,则在完成后将无法删除文本缓冲区,因为我不知道窗口过程何时将完成对消息的处理。

因此,我可以想到以下两个想法来从另一个线程访问UI控件:

  • 创建用户定义的消息,例如,我向UI线程发送如下内容:“将这200行(全部存储在一个字符串中,用'\n'分隔)插入ListViewX中”,以及在UI线程中收到此消息,它将更新ListViewX,完成后,它将删除字符串(在堆上分配)。
  • 另一种方法是将访问UI控件的代码放在函数内部,并将函数指针发送到UI线程,然后该UI线程将对其进行调用。

  • 这些方法中的一种是否提供了比其他方法更多的优势,并且还有其他方法可以做到这一点吗?

    最佳答案

    我经常使用以下模式(箭头表示“使用”关系):

               +---------------+                     
               | Communication |        +-----------+
          +--->+  Data Object  +<---+---+ Thread #0 |
          |    | (thread safe) |    |   +-----------+
          |    +---------------+    +---+ Thread #1 |
          |                         |   +-----------+
          |                         |     ...        
    +-----+----+                    |   +-----------+
    | Main (UI)|                    +---+ Thread N  |
    |  Thread  |                        +-----------+
    +----------+                                     
    
    Communication Data对象是线程安全的,通常是ref-counted(对于非GC语言很重要)。该对象提供了几种典型方法(全部可选,具体取决于实际用例):
  • 工作项目队列
  • 数据 getter / setter ,用于需要交换的任何其他数据
  • 进度信息将在用户界面中可视化
  • 中止/状态标志,结合...
  • 等待事件对象,用于发出各种信号

  • 因为数据对象会完全照顾自己,包括同步访问其数据,以及由于引用计数而或多或少地进行自动清理,所以最终将所有线程内容很好地封装到一个专用类中。我发现在各种情况下都非常方便。

    此外,方法将工作线程与UI 完全解耦,因此线程甚至根本不知道是否有UI以及它的外观:它是GUI吗?它是CLI吗?也许是网络服务?最后,由于UI线程(或其等效项)可以完全自行决定何时以及多长时间更新一次UI,因此它可以使UI保持响应。

    PS:可能有一个官方的GOF名称,不知道。

    关于multithreading - 如何从另一个线程访问UI控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29575203/

    相关文章:

    java - 多线程,Java 服务器/客户端项目

    c# - 当后台有大量代码时,如何让表单刷新?

    java - 为什么 java.util.concurrent.atomic.AtomicBoolean 在内部用 int 实现?

    c++ - 如何在 Win32 中重新绘制按钮?

    python - Windows:直接检查cp1252

    c# - 如何显示 Windows 登录对话框?

    multithreading - 如何在后台更新 MATLAB GUI?

    java - ftp 上的同时连接数

    c++ - 如何通过 DbgHelp 获取局部变量的值

    c++ - 提取特定的 Win32 函数