Win api的SendMessage永远等待

use*_*710 -4 java windows delphi winapi delphi-xe2

我在Windows 7 64位上有一个GUI应用程序(Service Pack 1)我的GUI应用程序中有一些Java并且它调度Delphi代码 -

最近,在升级到多核PC之后 - 我们注意到一些繁重的GUI动作会导致GUI卡住.我们只有一个更新GUI的线程.

在调试之后,我们注意到偶尔会有一个delphi用来赢取api的"SendMessage"的电话等待.

然后我们尝试将程序的亲和性设置为1 - 问题解决了,但它减慢了我们的应用程序.

我知道将SendMessage替换为PostMessage或SendMessageTimeout是很常见的,但是在很多地方我们使用SendMessage +我们也使用也使用SendMessage的DevExpress组件 - 我们不可能映射所有这些地方.

最奇怪的是,即使我们的GUI有一个线程,将亲和度设置为1也可以解决问题(系统中还有其他后台线程,但它们都是纯java并执行一些数据计算).

我的问题是:

  1. 任何已知的方法来解决这个问题?也许已知Windows 7中的错误?

  2. 我发送的邮件是否有可能丢失?总消息或速率是否有限制?如果是这样,我怎样才能增加这些限制?

  3. 我怎样才能获得更多信息 - 例如:在Windows的某个地方检查我的消息发生了什么 - 在哪里/为什么窗户被卡住等等.任何进一步分析问题的方法都将非常感激.

非常感谢你

Rem*_*eau 7

SendMessage()在跨线程边界发送消息时依赖于目标窗口的消息队列.这是记录在案的行为:

http://msdn.microsoft.com/en-us/library/ms644950.aspx

如果指定的窗口是由其他线程创建的,则系统会切换到该线程并调用相应的窗口过程.仅当接收线程执行消息检索代码时才处理线程之间发送的消息.发送线程被阻塞,直到接收线程处理该消息.

因此,SendMessage()在目标线程从其消息队列中检索到消息然后处理完全消息或在继续处理消息时调用ReplyMessage()release SendMessage()时,才会退出.

因此,如果SendMessage()卡住,则意味着目标线程没有处理其消息队列,这是一个很好的迹象,表明目标线程可能已经死锁,等待其他事情.

您的应用程序在锁定到1个CPU内核时运行正常但在允许在多个CPU内核上运行时出现问题意味着您的应用程序可能无法以多核安全方式执行线程间同步.在单核系统中,任何给定时刻只能有一个线程可以物理运行.由于操作系统使用线程调度和任务切换来处理并发的方式,在某些情况下,不安全的同步可能"足够安全".但是多个内核可以真正并行运行,因此运行在不同内核上的线程可以在同一时刻访问内存/资源,因此正确完成线程间同步以确保不允许这一点非常重要.发生这种情况,否则你的应用程序可能会与自身不同步,并且可能发生各种不良事件(例如 - 你的死锁).