Frage

Ich schreibe eine Anwendung zu starten und andere Anwendungen in C # zu überwachen. Ich verwende die System.Diagnostics.Process Klasse Anwendungen zu starten und überwachen dann die Anwendungen der Process.Responding Eigenschaft mit dem Stand der Anwendung abzufragen alle 100 milisecs. Ich benutze Process.CloseMainWindow die Anwendung zu stoppen oder Process.Kill es zu töten, wenn es nicht reagiert.

Ich habe ein seltsames Verhalten aufgefallen, wo manchmal das Prozessobjekt in einem Zustand erhält, wo die Reaktionseigenschaft immer gilt selbst zurückgibt, wenn der zugrunde liegende Prozess in einer Schleife hängt und wo es reagiert nicht auf Closemainwindow.

Eine Möglichkeit, es zu reproduzieren, ist die Reaktionseigenschaft direkt nach dem Starten der Prozessinstanz abzufragen. So zum Beispiel

_process.Start();
bool responding = _process.Responding;

wird der Fehlerzustand während

reproduzieren
_process.Start();
Thread.Sleep(1000);
bool responding = _process.Responding;

funktioniert. Die Reduzierung der Schlafperiode 500 wird wieder in den Fehlerzustand vor.

Etwas in _process.Responding Aufruf zu schnell nach dem Start erscheint das Objekt aus immer die richtigen Fenstern Message Queue-Handler zu verhindern. Ich denke, ich brauche für _process.Start zu warten ist es asynchrone Arbeit zu beenden tun. Gibt es einen besseren Weg, dies zu warten, als Thread.Sleep Aufruf? Ich bin nicht allzu zuversichtlich, dass die 1000 ms immer genug sein werden.

War es hilfreich?

Lösung

Nun, ich brauche diese später zu überprüfen, aber ich bin sicher, dass es eine Methode ist, die den Thread sagt zu warten, bis es eingabebereit ist. Überwachen Sie GUI Prozesse nur?

Ist das nicht Process.WaitForInputIdle keine Hilfe für Sie? Oder bin ich dabei den Punkt? :)

Update

ein Geplauder auf Twitter verfolgt (oder tweet-tweet?) Mit Mendelt dachte ich, ich soll meine Antwort aktualisieren, so dass die Gemeinschaft voll bewusst ist ..

  • WaitForInputIdle wird nur auf Anwendungen arbeiten, die eine grafische Benutzeroberfläche haben.
  • Sie die Zeit angeben, zu warten, und die Methode gibt einen bool, wenn der Prozess in diesem Zeitrahmen in einen Ruhezustand erreicht hat, kann man natürlich diese Schleife verwenden, wenn erforderlich, oder handhabt als angemessen.

Ich hoffe, das hilft:)

Andere Tipps

Ich denke, es besser sein kann, die Prüfung für _process.Responding zu verbessern, so dass Sie nur versuchen, den Prozess zu stoppen / töten, wenn die Reaktion Eigenschaft für mehr als 5 Sekunden (zum Beispiel) false zurück.

Ich glaube, dass sehr oft finden können Anwendungen sein können für eine split „reagiert nicht“ zweite, während sie eine intensivere Verarbeitung tun.

Ich glaube, ein milderer Ansatz besser funktioniert, so dass ein Prozess „reagiert nicht“ für ein kurze Zeit zu sein, nur Maßnahmen zu ergreifen, wenn sie immer wieder für einige Sekunden (oder wie lange Sie wollen) „reagieren nicht“ .

Weiterer Hinweis: Die Microsoft-Dokumentation gibt an, dass die Reaktion Eigenschaft speziell auf die Benutzeroberfläche betrifft, weshalb ein neu gestarteter Prozess nicht haben kann es UI ist reagiert sofort

.

Danke für die Antworten. Diese

_process.Start();
_process.WaitForInputIdle();

Es scheint, das Problem zu lösen. Es ist immer noch seltsam, weil Reaktion und WaitForInputIdle sollten beide den gleichen win32 api Anruf unter der Decke werden.

Einige weitere Hintergrundinformationen
GUI-Anwendungen haben ein Hauptfenster mit einer Nachrichten-Warteschlange. Als Reaktion und WaitForInputIdle arbeitet, indem geprüft wird, ob der Prozess noch Nachrichten von dieser Nachricht Warteschlange verarbeitet. Aus diesem Grunde ist sie nur mit GUI-Anwendungen arbeiten. Irgendwie scheint es, dass die Berufung reagieren zu schnell stört den Prozess mit immer einen Griff zu dieser Nachrichtenwarteschlange zu bekommen. Der Aufruf WaitForInputIdle scheint dieses Problem zu lösen.

Ich muss werde in Reflektor tauchen, um zu sehen, ob ich Sinn daraus machen kann.

update
Es scheint, dass mit dem Prozess verbunden ist nur der Fenstergriff Abrufen nach dem Start ist genug, um das seltsame Verhalten auszulösen. Wie folgt aus:

_process.Start();
IntPtr mainWindow = _process.MainWindowHandle;

ich mit Reflektor überprüft und das ist, was reagiert die Decke tut unter. Es scheint, dass, wenn Sie die Mainwindowhandle erhalten zu schnell Sie den falschen bekommen und es verwendet diese falsch handelte es für den Rest der Laufzeit des Prozesses oder bis Sie rufen Refresh ();

update
Der Aufruf WaitForInputIdle () löst das Problem nur einen Teil der Zeit. Der Aufruf Refresh () jedes Mal lesen Sie die Reaktion Eigenschaft scheint besser zu funktionieren.

Ich bemerkte auch, dass in einem Projekt vor etwa 2 Jahren. Ich rief .Refresh () vor bestimmten prop Werte anfordert. Es war eine Trial-and-Error-Methode zu finden, wenn ich .Refresh nennen benötigt ().

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top