SendMessage (HWND_BROADCAST, ....) зависает - PullRequest
14 голосов
/ 23 декабря 2009

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

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

Ответы [ 4 ]

19 голосов
/ 24 декабря 2009

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

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

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

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

3 голосов
/ 23 декабря 2009

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

0 голосов
/ 23 декабря 2009

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

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

0 голосов
/ 23 декабря 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...