我总是听说我应该只从GUI线程操作GUI控件,但我不明白从另一个线程这样做有什么问题。
我的意思是如果我想要更改Window的标题栏文本,我需要做的就是向Window的消息队列发送消息。那么从另一个线程做到这一点有什么不对呢?
答案 0 :(得分:2)
HWND与创建它的线程具有亲缘关系。只有拥有线程才能破坏HWND,只有拥有线程才能通过拥有线程的消息队列接收发布到HWND的消息。如果消息由拥有线程发送直接发送给HWND,则立即调用HWND的窗口过程,否则通过拥有线程的消息循环调度它(不是与拥有线程的消息队列混淆。无论哪种方式,HWND的窗口过程总是在拥有线程的上下文中执行。
拥有线程也可能与HWND关联数据,或者使用来自HWND的通知来操纵其他数据/ HWND,这些数据/ HWND不受跨线程并发访问的保护。
因此,只有拥有的线程才能以任何方式操纵HWND及其数据。
现在,有一些例外情况,例如WM_SETTEXT
。但除非你确定任何给定的消息都是线程安全的,否则假设它不是,并通过拥有线程委托对HWND的所有访问。
答案 1 :(得分:0)
您要避免的主要是由程序执行其他操作导致的图形延迟。除此之外,这是一个程序设计问题。如果另一个线程挂起,等待它通常做的事情,那么就不会执行SendMessage()。
然后,您在图形更新和任何不相关的任务之间创建了紧密耦合,这使得其他线程保持忙碌。程序设计方面,例如文件处理线程更新图形没有任何意义,即使这样做不一定会导致图形滞后。
答案 2 :(得分:0)
无法从UI线程以外的其他线程“操纵”UI元素 - 如果您发送MESSAGES,您将间接排队命令,然后在消息队列中处理这些命令,可能导致状态更改目标UI元素 - 这是在UI线程上自动完成的。
多线程UI元素控制没有任何问题,只要你知道自己在做什么 - 一个非常简单的方法就是通过windows消息实现它,但如果你当前的任务有点复杂,这些可能会变得乏味;在这些情况下,通常最好创建一个中心类,它接受来自任意线程的“UI控制命令”,如果可能的话,在UI线程上对它们进行顺序化和执行。 您还可以临时将线程上下文切换到主UI线程,有效地将当前线程转换为UI - 线程:https://msdn.microsoft.com/en-us/library/windows/desktop/ms633525%28v=vs.85%29.aspx 我从来没有用过这种方法,这种方法对我来说似乎很......有问题