Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 不使用SendMessage()从其他线程访问UI控件的原因?_Multithreading_Winapi - Fatal编程技术网

Multithreading 不使用SendMessage()从其他线程访问UI控件的原因?

Multithreading 不使用SendMessage()从其他线程访问UI控件的原因?,multithreading,winapi,Multithreading,Winapi,我已经读到SendMessage()不应该用于从其他线程访问UI控件,但我不知道为什么,我能想到的唯一原因是因为SendMessage()是一个阻塞调用,在某些情况下可能会导致死锁 但这是不使用它的唯一原因吗 编辑:这篇文章讨论了不使用SendMessage()的原因,但我觉得它不是很清楚(它是为.NET设计的)。最好记住,编写正确代码的几率不是很高。一般的建议是不要这样做!在Windows中,GUI程序的UI线程是完全结构化的,可以使在另一个线程上或进程内运行的代码影响程序的UI。消息循环的

我已经读到
SendMessage()
不应该用于从其他线程访问UI控件,但我不知道为什么,我能想到的唯一原因是因为
SendMessage()
是一个阻塞调用,在某些情况下可能会导致死锁

但这是不使用它的唯一原因吗



编辑:这篇文章讨论了不使用
SendMessage()
的原因,但我觉得它不是很清楚(它是为.NET设计的)。

最好记住,编写正确代码的几率不是很高。一般的建议是不要这样做!在Windows中,GUI程序的UI线程是完全结构化的,可以使在另一个线程上或进程内运行的代码影响程序的UI。消息循环的点,消息循环的通用解决方案。PostMessage()是您利用它的武器

在您继续前进之前,请先考虑一个使用SendMessage时很难解决的简单问题。如何安全正确地关闭窗户

假设您需要关闭窗口的确切时间完全不可预测,并且与工作线程的执行完全不同步。用户关闭它,或要求UI线程终止,您需要确保线程已退出并停止调用SendMessage,然后才能真正关闭窗口

直观的方法是在WM_CLOSE消息处理程序中发出事件信号,要求线程停止。然后等待它完成,然后窗口可以关闭。直观,但它不起作用,它会使您的程序死锁。有时,并非总是,很难调试。当线程无法检查事件时出错,因为它卡在SendMessage调用中。无法完成,因为UI线程正在等待线程退出。工作线程无法继续,UI线程无法继续。一个“致命的拥抱”,你的程序将被挂起,需要被强行杀死。死锁是一个标准的线程错误

您会大声喊,“我将使用SendMessageTimeout!”但是对于uTimeout参数,您会传递什么,以及如何解释错误\u TIMEOUT错误?UI线程在一段时间内变得紧张是很常见的,当然你以前见过“鬼窗口”,在标题栏中显示“没有响应”。因此,除非将uTimeout设置得非常大,否则错误\u超时不能可靠地指示UI线程正在尝试关闭。至少10秒。这种方法很管用,不过在出口处偶尔挂上10秒钟也不太好看

解决所有消息的此类问题,而不仅仅是WM_CLOSE。WM_油漆应该是下一个,另一个很难干净地解决的问题。工作线程在UI线程调用EndPaint()前一毫秒要求更新显示。因此,永远不会显示更新,它只会丢失。线程竞赛,另一个标准线程错误

第三个经典的线程错误是消防水管问题。当工作线程生成结果的速度快于UI线程处理结果的速度时发生。非常常见,UI更新非常昂贵。易于检测,很难解决,发生时不可预测。易于检测,因为您的UI将冻结,UI线程会燃烧100%的内核以跟上消息速率。它不再处理低优先级的任务。我喜欢绘画。使用SendMessage或PostMessage时都会出错。在后一种情况下,您将填充消息队列,直到达到最大容量。它包含10000条未处理的消息后开始失败


长话短说,SendMessage()是线程安全的。但是线程安全不是一个可传递的属性,它不会自动使您自己的代码线程安全。当您使用线程时,您仍然会遇到所有可能出错的问题。死锁,赛车,消防水管。害怕线程野兽。

最好记住,编写正确代码的几率不是很高。一般的建议是不要这样做!在Windows中,GUI程序的UI线程是完全结构化的,可以使在另一个线程上或进程内运行的代码影响程序的UI。消息循环的点,消息循环的通用解决方案。PostMessage()是您利用它的武器

在您继续前进之前,请先考虑一个使用SendMessage时很难解决的简单问题。如何安全正确地关闭窗户

假设您需要关闭窗口的确切时间完全不可预测,并且与工作线程的执行完全不同步。用户关闭它,或要求UI线程终止,您需要确保线程已退出并停止调用SendMessage,然后才能真正关闭窗口

直观的方法是在WM_CLOSE消息处理程序中发出事件信号,要求线程停止。然后等待它完成,然后窗口可以关闭。直观,但它不起作用,它会使您的程序死锁。有时,并非总是,很难调试。当线程无法检查事件时出错,因为它卡在SendMessage调用中。无法完成,因为UI线程正在等待线程退出。工作线程无法继续,UI线程无法继续。一个“致命的拥抱”,你的程序将被挂起,需要被强行杀死。死锁是一个标准的线程错误

您会大声喊,“我将使用SendMessageTimeout!”但是对于uTimeout参数,您会传递什么,以及如何解释错误\u TIMEOUT错误?UI线程在一段时间内变得紧张是很常见的,当然你已经看到了“鬼窗口”