2009-12-23 8 views
11

Wenn ich Sendmessage-Funktion mit HWND_BROADCAST verwenden, die Anwendung auflegt. Gibt es keine Antwort von der Anwendung für lange Zeit.Sendmessage (HWND_BROADCAST hängt

Kann mir jemand erklären, warum?

Antwort

2

Dies liegt daran, Sendmessage callte mit HWND_BROADCAST zählt zuerst alle verfügbaren Fenster auf und ruft dann SendMessage für jedes dieser Fenster auf.SendMessage kehrt erst zurück, wenn das Fenster die Verarbeitung der Nachricht beendet hat.Wenn ein einzelnes Fenster eine lange Zeit benötigt, um die Nachricht zu verarbeiten, wird der gesamte Anruf verzögert

+1

Schlimmer noch, wenn man die aufgerufenen Fensterprozeduren * nie * zurückgibt, wird weder SendMessage(), und die Anwendung wird dauerhaft hängen. Im Allgemeinen haben Sie keine Möglichkeit zu wissen, wie das Fenster einer anderen Anwendung auf eine beliebige Nachricht reagiert (sogar eine, die mit RegisterMessage() erstellt wurde). Einfach gesagt, sollten Sie SendMessage() nie aufrufen, um eine Nachricht an ein Fenster zu senden, wenn Sie nicht genau wissen, was dieses Fenster ist und wie es reagieren wird. –

0

Es gibt ein SendMessageTimeout Dadurch wird die Zeit begrenzt, die Ihre Anwendung blockiert, während sie auf die Annahme des Empfängers wartet.

Eine andere Problemumgehung besteht darin, mehrere Threads zu starten und mehrere Nachrichten gleichzeitig zu liefern (d. H. Parallel dazu). Dann, wenn einer der Empfänger hängt, töten Sie nicht Ihre gesamte App.

0

Es gibt mindestens einen Prozess, der eine Nachrichtenpumpe hat, aber keine Nachrichten pumpt. SendMessage kehrt erst zurück, wenn alle Empfänger die Nachricht verarbeitet haben ... also kehrt sie nicht zurück. Sie können stattdessen versuchen, SendMessageTimeout zu verwenden, um dies zu umgehen.

Im Übrigen kann das Starten eines Prozesses und das Warten auf seinen Prozessgriff mit Problemen behaftet sein. Ich beschreibe dies auf meiner Website here.

15

Dies geschieht, wenn es einen Prozess gibt, der ein Top-Level-Fenster hat, aber GetMessage oder PeekMessage nicht für den Thread aufruft, der das Fenster erstellt hat.

Aus Gründen der Abwärtskompatibilität mit Windows 3.0 wird SendMessage erst zurückgegeben, wenn alle Fenster der obersten Ebene im System auf Ihre Übertragung geantwortet haben. Dieses Verhalten machte Sinn, bevor Windows Multithread wurde, da SendMessage() auch beim Senden an andere Prozesse niemals blockieren würde.

Aber beginnend mit Win32, wenn Sie SendMessage zu einem Fenster in einem anderen Prozess, was tatsächlich passiert, ist Ihr Thread blockiert, bis der Thread in dem anderen Prozess aufwacht und die Nachricht verarbeitet. Wenn dieser Thread beschäftigt ist oder einfach keine Nachrichten pumpt, dann wartest du für immer.

Aus diesem Grund sollten Sie immer SendNotifyMessage oder SendMessageTimeout verwenden, wenn Sie HWND_BROADCAST verwenden oder auf andere Weise Nachrichten an Windows senden, die anderen Prozessen gehören.

Verwandte Themen