Ich habe ein ähnliches Problem wie das hier beschriebene: Ссылка
Dieser Thread schlägt vor, dass Task-Manager WM_NULL an den Prozess sendet und erwartet, dass der Prozess diese Nachricht innerhalb der Zeitlimitüberschreitung (5 Sekunden?) verwendet. Wenn ich nach "WM_NULL hung" suche, gibt es viele Hinweise auf die gleiche Technik.
Ich sehe jedoch keine WM_NULL-Nachrichten in der Warteschlange meiner Anwendung, während es bei einer langwierigen Operation funktioniert - ich habe einen sekundären Thread, der alle 0,5 Sek. zum Hauptthread wechselt und PeekMessage () auf der Suche nach WM_NULL und es findet keine!
Also, was ist die Methode, die Windows (Vista) verwendet, um festzustellen, ob eine Anwendung hängt?
Welche Nachrichten sollte meine Anwendung verwenden, damit Windows denkt, dass die Anwendung reagiert?
MEHR DETAILS:
Zusammen mit PeekMessage () suchen wir nach WM_NULL, wir rufen PeekMessage () auch für Mausereignisse auf, da wir auch verstehen wollen, ob der Benutzer bestimmte Bereiche des Fensters ausgewählt hat, in denen ein Stoppschild gezeichnet wird. Wenn der Bereich ausgewählt ist, setzen wir ein Flag, das die langwierige Operation im Hauptthread regelmäßig überprüft und stoppt, wenn das Stoppzeichen ausgewählt wird. Das Problem mit Vista ist, dass wenn es die Anwendung als nicht reagierend deklariert, es sein Fenster durch ein Geisterfenster ersetzt - siehe Beschreibung von PeekMessage () :
Wenn ein Fenster der obersten Ebene für mehr als einige Sekunden nicht mehr auf Nachrichten reagiert, betrachtet das System das Fenster als nicht reagierend und ersetzt es durch ein Geisterfenster mit den gleichen Attributen z-Reihenfolge, Standort, Größe und visuell . Dies ermöglicht dem Benutzer, es zu verschieben, die Größe zu ändern oder sogar die Anwendung zu schließen. Dies sind jedoch die einzigen verfügbaren Aktionen, da die Anwendung tatsächlich nicht reagiert. Wenn eine Anwendung debuggt wird, erzeugt das System kein Geisterfenster.
In diesem Ghost-Fenster können Mauspfeile nicht durch unser Fenster gehen, weil das Fenster nicht mehr auf dem Bildschirm angezeigt wird! Also mein Ziel ist es zu verhindern, dass dieses Geisterfenster an erster Stelle erscheint ...
Nach einigen weiteren Untersuchungen:
Nachdem ich den Code Michael vorgeschlagen in seiner Antwort auf diese Frage
hinzugefügt habe %Vor%Die Anwendung wird von Windows nicht mehr gehängt; Allerdings kann ich diese Lösung nicht verwenden, da die Anwendung auf Auswahlmöglichkeiten für verschiedene Schaltflächen usw. reagiert (was nicht passieren sollte). Also habe ich versucht zu sehen, welche Nachrichten kommen. Ich habe Spy ++ und auch Debug drucken, und beide zeigten nur zwei Arten von Nachrichten: WM_TIMER und 0x0118 (WM_SYSTIMER). Also habe ich den Code so modifiziert.
%Vor%Überraschenderweise hängt die Anwendung wieder !!
Jetzt bin ich wirklich festgefahren. Wenn ich die einzigen eingehenden Nachrichten abfange und sie von der Anwendung verarbeiten lasse, warum denkt Windows immer noch, dass die Anwendung keine Ereignisse verarbeitet?
Jeder sinnvolle Vorschlag wäre sehr geschätzt.
TaskManager verwendet wahrscheinlich IsHungAppWindow , um festzustellen, ob eine Anwendung angehalten wurde. Nach einer MSDN gilt eine Anwendung als blockiert, wenn sie nicht auf Eingaben wartet, sich nicht in der Startverarbeitung befindet oder Nachrichten nicht innerhalb von 5 Sekunden verarbeitet hat. Also kein WM_NULL notwendig.
Sie müssen keine bestimmten Nachrichten konsumieren - pumpen Sie regelmäßig Nachrichten und verschieben Sie lange Aufgaben vom UI-Thread. Wenn Sie PeekMessage alle 0,5 Sekunden aufrufen können, ersetzen Sie sie wie folgt:
%Vor%Dadurch wird Ihre Nachrichtenwarteschlange vollständig entlastet und Sie reagieren schneller auf den Benutzer. Filtern Sie nicht einzelne Nachrichten wie z. B. Mausnachrichten. Sie sollten dies mehr als alle 0,5 Sekunden tun, wenn möglich, und längerfristig versuchen, die lange Arbeit des UI-Threads zu verschieben.
Die Lösung ist ein zusätzlicher Anruf nach dem Versenden Ihrer Nachrichten.
%Vor%Tags und Links windows windows-vista windows-xp