C语言 从另一个线程操作 GUI 控件是否有任何错误



我总是听说我应该只从 GUI 线程操作 GUI 控件,但我不明白从另一个线程这样做有什么问题。

的意思是,如果我想更改窗口的标题栏文本,我需要做的就是向窗口的消息队列发送消息。那么从另一个线程执行此操作有什么问题呢?

HWND 与创建它的线程具有关联性。 只有拥有线程可以销毁 HWND,并且只有拥有线程才能接收通过拥有线程的消息队列发布到 HWND 的消息。 如果消息由拥有线程直接发送到 HWND,则会立即调用 HWND 的窗口过程,否则通过拥有线程的消息循环调度它(不要与拥有线程的消息队列混淆)。 因此,无论哪种方式,HWND 的窗口过程始终在所属线程的上下文中执行。

所属线程可能还将数据与 HWND 关联,或使用来自 HWND 的通知来操作其他数据/HWND,这些数据/HWND 不受跨线程并发访问的保护。

因此,只有拥有线程才能以任何方式操作 HWND 及其数据。

现在,有一些例外,例如WM_SETTEXT。 但是,除非您确定任何给定的消息是线程安全的,否则假设它不是,并通过所属线程委派对 HWND 的所有访问权限。

您要避免的主要事情是由程序执行其他操作引起的图形滞后。除此之外,这是一个程序设计问题。如果另一个线程挂起,等待它通常正在做的事情,那么不会执行任何 SendMessage()。

然后,您在图形更新和任何不相关的任务之间创建了一个紧密的耦合,这使另一个线程保持忙碌。在程序设计方面,例如,让文件处理线程更新图形没有任何意义,即使这样做不一定会导致图形滞后。

不可能从 UI 线程

以外的其他线程"操作"UI 元素 - 如果您正在发送 MESSAGES,您将间接排队命令,然后在 messagequeue 上处理这些命令,并可能导致目标 UI 元素的状态更改 - 这是在 UI 线程上自动完成的。

只要你知道自己在做什么,多线程 UI 元素控制就没有错 - 一种非常简单的方法是通过 Windows 消息,但如果你当前的任务有点复杂,这些可能会变得乏味;在这些情况下,通常最好创建一个中心类来接受来自任意线程的"UI 控制命令", 如果可能,在 UI 线程上按顺序化和执行它们。您还可以暂时将线程上下文切换到主 UI 线程,从而有效地将当前线程转换为 UI - 线程 : https://msdn.microsoft.com/en-us/library/windows/desktop/ms633525%28v=vs.85%29.aspx我从来没有用过这个,这种方法似乎很......对我来说有问题

相关内容

最新更新