从另一个线程操作GUI控件有什么问题吗?

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

我的意思是如果我想更改Window的标题栏文本,我需要做的就是向Window的消息队列发送消息。 那么从另一个线程做到这一点有什么不对?

HWND与创建它的线程具有亲缘关系。 只有拥有线程才能破坏HWND,只有拥有线程才能接收通过拥有线程的消息队列发布到HWND的消息。 如果消息由拥有线程直接发送到HWND,则立即调用HWND的窗口过程,否则通过拥有线程的消息循环调度它(不要与拥有线程的消息队列混淆)。 无论哪种方式,HWND的窗口过程总是在拥有线程的上下文中执行。

拥有线程还可以与HWND关联数据,或者使用来自HWND的通知来操纵其他数据/ HWND,这些数据/ HWND不受跨线程的并发访问的保护。

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

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

您要避免的主要问题是程序执行其他操作导致的图形延迟。 除此之外,这是一个程序设计问题。 如果另一个线程挂起,等待它正常做的事情,那么就不会执行SendMessage()。

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

除了UI线程之外,不可能从其他线程“操纵”UI元素 – 如果您发送MESSAGES,您将间接排队命令,然后在消息队列中处理这些命令,并可能导致目标UI元素的状态更改 – 这是在UI线程上自动完成。

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