use*_*812 0 winapi multithreading
我已经读过SendMessage()不应该用来从其他线程访问UI控件,但是我不知道我知道为什么,我能想到的唯一原因是因为SendMessage()是阻塞调用,那么它可能会在某些情况下导致死锁.
但这是不使用它的唯一原因吗?
编辑:该文章有关会谈的理由不使用SendMessage(),但我不觉得这是非常明确的(它是用于.NET).
最好记住,你编写正确代码的几率并不是很好.通用的建议是不要这样做! 这是从来没有必要,在Windows GUI程序的UI线程是完全结构化,使之简单,以允许在另一个线程或进程中影响程序的UI运行的代码.消息循环的要点,生产者 - 消费者问题的通用解决方案.PostMessage()是你利用它的武器.
在你继续前进之前,首先要考虑一个在使用SendMessage时很难解决的简单问题.如何安全正确地关闭窗户?
鉴于您需要关闭窗口的确切时刻是完全不可预测的,并且与工作线程的执行完全不同步.用户关闭它,或要求UI线程终止,您需要确保线程已退出并停止调用SendMessage,然后才能实际关闭窗口.
直观的方法是在WM_CLOSE消息处理程序中发出事件信号,要求线程停止.等待它完成,然后窗口可以关闭.直观,但它不起作用,它会使你的程序陷入僵局.有时候,并不总是很难调试.当线程无法检查事件时出错,因为它卡在SendMessage调用中.由于UI线程正在等待线程退出,因此无法完成.工作线程无法继续,UI线程无法继续.一个"致命的拥抱",你的程序将挂起并需要被强行杀死.死锁是一个标准的线程错误.
你会喊道,"我会使用SendMessageTimeout!" 但是你为uTimeout参数传递了什么?你如何解释ERROR_TIMEOUT错误?对于一个UI线程来说,一段时间内是紧张性精神紧张是非常常见的,当然你之前已经看过"鬼窗口",在标题栏中显示"无响应".因此,除非使uTimeout非常大,否则ERROR_TIMEOUT无法可靠地指示UI线程正在尝试关闭.至少10秒.这有点起作用,但偶尔在出口处停留10秒并不是很漂亮.
解决所有消息的这种问题,而不仅仅是WM_CLOSE.WM_PAINT应该是下一个,另一个非常非常难以彻底解决的问题.您的工作线程要求在UI线程调用EndPaint()之前一毫秒更新显示.因此从不显示更新,它只是迷路了.线程竞争,另一个标准线程错误.
第三个经典的线程错误是火管问题.当您的工作线程产生的结果比UI线程可以处理它们更快时,就会发生这种情况.非常常见的UI更新非常昂贵.易于检测,很难解决,并且在发生时难以预测.由于UI会冻结,因此易于检测,UI线程会烧掉100%的核心,试图跟上消息速率.它不再能够解决它的低优先级任务了.喜欢画画.不顺心都当您使用SendMessage函数或PostMessage的.在后一种情况下,您将填充消息队列以达到容量.它包含10000个未处理的消息后开始失败.
简而言之,是的,SendMessage()是线程安全的.但线程安全不是传递属性,它不会自动使您自己的代码线程安全.当你使用线程时,你仍然会遇到所有可能出错的事情.僵局,种族,火灾.害怕穿线的野兽.
| 归档时间: |
|
| 查看次数: |
618 次 |
| 最近记录: |