2009-12-23 9 views
11

Cuando uso la función SendMessage con HWND_BROADCAST, la aplicación cuelga. No hay respuesta por parte de la solicitud de mucho tiempo.SendMessage (HWND_BROADCAST cuelga

¿Puede alguien explicar por qué?

Respuesta

2

Esto es debido a SendMessage llama con HWND_BROADCAST primero enumera todas las ventanas disponibles y luego llama a SendMessage para cada una de esas ventanas. SendMessage no volverá hasta que la ventana haya terminado de procesar el mensaje. Si una sola ventana tarda mucho tiempo en procesar el mensaje, toda la llamada se retrasará

+1

Peor aún, si uno de los llamados procedimientos de ventana * nunca * regresa, tampoco lo hará SendMessage(), y la aplicación se bloqueará permanentemente. En general, no tiene forma de saber cómo responderá la ventana de otra aplicación a un mensaje arbitrario (incluso uno creado con RegisterMessage()). En pocas palabras, nunca debe llamar a SendMessage() para enviar un mensaje a una ventana a menos que sepa exactamente qué es esa ventana y cómo responderá. –

0

Hay un SendMessageTimeout lo que limitará la cantidad de tiempo que su aplicación se bloquea mientras espera que el receptor lo acepte.

Otra solución consiste en iniciar varios subprocesos y hacer que entreguen varios mensajes a la vez (es decir, en paralelo). Entonces, si uno de los receptores está colgado, no mata toda su aplicación.

0

Hay al menos un proceso que tiene una bomba de mensajes pero no está bombeando mensajes. SendMessage no regresa hasta que todos los receptores hayan procesado el mensaje ... para que no vuelva. Puede intentar usar SendMessageTimeout para evitar esto.

Dicho sea de paso, esta es la razón por la cual el inicio de un proceso y la espera en el manejo del proceso pueden estar plagados de problemas. Lo describo en mi sitio web here.

15

Esto sucederá cuando hay un proceso que tiene una ventana de nivel superior, pero no está llamando a GetMessage o PeekMessage en la secuencia que creó la ventana.

Para compatibilidad con Windows 3.0, SendMessage no volverá hasta que todas las ventanas de nivel superior en el sistema hayan respondido a su difusión. Este comportamiento tenía sentido antes de que Windows fuera multiproceso, porque SendMessage(), incluso cuando se enviaba a otros procesos, nunca se bloquearía.

Pero comenzando con Win32, cuando envía un mensaje a una ventana en otro proceso, lo que realmente sucede es que su hilo bloquea hasta que el hilo en el otro proceso se despierta y maneja el mensaje. Si ese hilo está ocupado, o simplemente no está bombeando mensajes, esperas por siempre.

Por esa razón, siempre debe usar SendNotifyMessage o SendMessageTimeout cuando utiliza HWND_BROADCAST, o envía mensajes a ventanas propiedad de otros procesos.