2009-12-23 8 views
11

Quand j'utilise la fonction SendMessage avec HWND_BROADCAST, l'application raccroche. Il n'y a pas de réponse de la demande depuis longtemps.SendMessage (HWND_BROADCAST se bloque

Quelqu'un peut-il expliquer pourquoi?

Répondre

2

Ceci est parce SendMessage appelé avec HWND_BROADCAST commence par énumérer toutes les fenêtres disponibles, puis appelle SendMessage pour chacune de ces fenêtres SendMessage ne retournera pas tant que la fenêtre n'aura pas fini de traiter le message Si une seule fenêtre prend beaucoup de temps à traiter le message, l'appel entier sera retardé

+1

Pire encore, si l'une des procédures de fenêtres appelées * jamais * ne renvoie ni SendMessage(), et l'application va se bloquer définitivement. De manière générale, vous n'avez aucun moyen de savoir comment la fenêtre d'une autre application répondra à un message arbitraire (même celui créé avec RegisterMessage()). Autrement dit, vous ne devriez jamais appeler SendMessage() pour envoyer un message à une fenêtre à moins que vous ne sachiez exactement quelle est cette fenêtre et comment elle va répondre. –

0

Il existe un SendMessageTimeout ce qui limitera le temps que votre application bloque en attendant l'acceptation du récepteur. Une autre solution consiste à lancer plusieurs threads et à leur envoyer plusieurs messages à la fois (c'est-à-dire en parallèle). Ensuite, si l'un des récepteurs est bloqué, vous ne tuez pas votre application entière.

0

Il existe au moins un processus qui a une pompe de message mais qui ne pompe pas les messages. SendMessage ne retourne pas tant que tous les destinataires n'ont pas traité le message ... donc il ne retourne pas. Vous pouvez essayer d'utiliser SendMessageTimeout à la place pour contourner cela. Par ailleurs, c'est la raison pour laquelle le lancement d'un processus et l'attente de sa poignée de processus peuvent poser de nombreux problèmes. Je décris ceci sur mon site Web here.

15

Cela se produit lorsqu'un processus a une fenêtre de niveau supérieur, mais n'appelle pas GetMessage ou PeekMessage sur le thread qui a créé la fenêtre. Pour la rétrocompatibilité avec Windows 3.0, SendMessage ne retournera pas tant que toutes les fenêtres de niveau supérieur du système n'auront pas répondu à votre diffusion. Ce comportement avait du sens avant Windows était multithread, car SendMessage(), même lors de l'envoi à d'autres processus ne bloquerait jamais. Mais à partir de Win32, lorsque vous envoyez un message à une fenêtre dans un autre processus, ce qui se passe réellement, c'est vos blocs de threads jusqu'à ce que le thread de l'autre processus se réveille et gère le message. Si ce fil est occupé, ou simplement ne pas pomper des messages, alors vous attendez toujours. Pour cette raison, vous devez toujours utiliser SendNotifyMessage ou SendMessageTimeout lorsque vous utilisez HWND_BROADCAST ou que vous envoyez des messages à d'autres processus appartenant à d'autres fenêtres.