SendMessage (HWND_BROADCAST зависает

Когда я использую функцию SendMessage с HWND_BROADCAST, приложение зависает. от приложения в течение длительного времени нет ответа.

Может кто-нибудь объяснить, почему?

Ответ 1

Это произойдет, когда есть процесс, который имеет окно верхнего уровня, но не вызывает GetMessage или PeekMessage в потоке, который создал окно.

Для обратной совместимости с Windows 3.0 SendMessage не вернется, пока все окна верхнего уровня в системе не ответят на вашу трансляцию. Такое поведение имело смысл, прежде чем Windows была многопотоковой, поскольку SendMessage() даже при отправке в другие процессы никогда не будет блокироваться.

Но начиная с Win32, когда вы отправляете сообщение в окно в другом процессе, то, что на самом деле происходит, это ваши потоковые блоки, пока поток в другом процессе не просыпается и не обрабатывает сообщение. Если этот поток занят или просто не перекачивает сообщения, вы ждете вечность.

По этой причине вы всегда должны использовать SendNotifyMessage или SendMessageTimeout при использовании HWND_BROADCAST или иначе отправлять сообщения в окна, принадлежащие другим процессам.

Ответ 2

Это связано с тем, что SendMessage, вызываемый с помощью HWND_BROADCAST, сначала перечисляет все доступные окна, а затем вызывает SendMessage для каждого из этих окон. SendMessage не вернется, пока окно не завершит обработку сообщения. Если одно окно занимает много времени для обработки сообщения, весь вызов будет отложен.

Ответ 3

Существует SendMessageTimeout, который будет ограничивать время, в течение которого ваши блоки приложений будут ждать приемника.

Другим обходным решением является запуск нескольких потоков и их одновременное предоставление нескольких сообщений (т.е. параллельно). Затем, если один из приемников висит, вы не убиваете все свое приложение.

Ответ 4

Существует, по крайней мере, один процесс, который имеет насос сообщений, но не передает сообщения. SendMessage не возвращается, пока все получатели не обработали сообщение... поэтому он не возвращается. Вы можете попробовать использовать SendMessageTimeout, чтобы обойти это.

Кстати, вот почему запуск процесса и ожидание его дескриптора процесса могут быть сопряжены с проблемами. Я описываю это на своем веб-сайте здесь.