Monday 20 March 2017

C Standard Output Waitforexit Doesnt Warten

Ich benutze Process. Start, um eine Batchdatei zu starten. Die Batchdatei verwendet den START-Befehl, um mehrere Programme parallel zu starten und dann zu beenden. Sobald die Batchdatei fertig ist, wird Process. HasExited wahr und Process. ExitCode enthält den korrekten Exit-Code. Aber wenn ich Process. WaitForExit () aufrufe, hängt es nie wieder. Das folgende Codebeispiel zeigt das Problem. Es erstellt eine Batch-Datei, startet es und druckt dann: Es sollte dann drucken: aber es funktioniert nie (obwohl HasExited ist wahr und wir haben bereits einen ExitCode). Mir ist aufgefallen, dass dies nur geschieht, wenn die Batchdatei START-Befehle enthält und wenn Standardausgabe und Standardfehler umgeleitet werden. Warum hat WaitForExit () nie wieder Was ist der richtige Weg, um für einen solchen Prozess warten zu warten, ist es sicher, nur Abfrage Process. HasExited oder kann das Ergebnis in anderen Problemen PS. Ich habe gerade festgestellt, dass das Aufrufen von WaitForExit (100000) mit einem riesigen Timeout (das definitiv nicht abläuft) zurückgibt sofort, wenn der Prozess beendet wird. Wierd. Ohne Timeout hängt es. Es gibt einen grundlegenden Unterschied, wenn Sie WaitForExit () ohne ein Timeout aufrufen, es stellt sicher, dass die umgeleiteten stdouterr EOF zurückgegeben haben. Dies stellt sicher, dass Sie alle gelesen haben, die Ausgabe, die durch den Prozess produziert wurde. Wir können nicht sehen, was quotonOutputquot tut, aber hohe Chancen, dass es Deadlocks Ihr Programm, weil es etwas Bösartiges wie Annahme, dass Ihr Haupt-Thread im Leerlauf ist, wenn es tatsächlich in WaitForExit () stecken tut. Ndash Hans Passant Nov 3 14 am 12:06 Das scheint ein Artefakt zu sein (Id say bug) in der spezifischen Implementierung der ereignisbasierten asynchronen Handhabung von StandardOutput und StandardError. Ich bemerkte, dass, während ich konnte leicht zu reproduzieren Ihr Problem, indem Sie einfach den Code, den Sie zur Verfügung gestellt (exzellent Code-Beispiel, übrigens)), hielt der Prozess nicht wirklich unbegrenzt. Vielmehr kehrte es von WaitForExit () zurück, nachdem beide der untergeordneten Prozesse selbst gestartet waren. Dies scheint ein absichtlicher Teil der Implementierung der Process-Klasse zu sein. Insbesondere überprüft es in der Process. WaitForExit () - Methode, sobald es das Warten auf den Prozess-Handle selbst beendet hat, ob ein Leser für stdout oder stderr erstellt wurde, falls dies der Fall ist und wenn der Timeoutwert für die WaitForExit ( ) Aufruf ist unendlich (dh -1), der Code wartet tatsächlich auf den End-of-Stream auf den Leser (n). Jeder entsprechende Leser wird nur erstellt, wenn die Methode BeginOutputReadLine () oder BeginErrorReadLine () aufgerufen wird. Die Stdout - und Stderr-Ströme werden erst geschlossen, wenn die Kindprozesse geschlossen sind. So warten auf das Ende dieser Ströme wird blockiert, bis das geschieht. Das WaitForExit () sollte sich anders verhalten, je nachdem, ob man eine der Methoden aufgerufen hat, die das ereignisbasierte Lesen der Streams starten oder nicht, und vor allem, dass das Lesen dieser Streams nicht direkt dazu führt, dass WaitForExit () sich so verhält Eine Inkonsistenz in der API, die es viel schwieriger zu verstehen und zu verwenden macht. Während Id persönlich nennen dies ein Bug, ich vermute, seine mögliche, dass die Implementierung (en) der Process-Klasse sind sich dieser Inkonsistenz bewusst und schuf sie mit Absicht. In jedem Fall wäre das Work-around zu lesen StandardOutput und StandardError direkt statt der Verwendung der ereignisbasierten Teil der API. (Natürlich, wenn diejenigen Code auf diesen Streams warten, würde man das gleiche Blocking-Verhalten zu sehen, bis das Kind Prozesse schließen.) Zum Beispiel (C, weil ich nicht wissen, F gut genug, um ein Codebeispiel wie diese zusammen schnell schlagen :)): Hoffentlich wird die oben genannten Work-around oder etwas ähnliches auf die grundlegende Frage Sie in laufen. Mein Dank an den Kommentator Niels Vorgaard Christensen für die Leitung mich zu den problematischen Linien in der WaitForExit () - Methode, so dass ich diese Antwort verbessern konnte. Basiert auf meinem Verständnis, die Process. WaitForExit (int32) - Methode bedeutet nicht, wenn Timeout beenden. Die WaitForExit (Int32) Überlastung wird verwendet, um den aktuellen Thread zu warten, bis der zugehörige Prozess beendet wird. Diese Überladung weist die Prozesskomponente an, eine endliche Zeitdauer zu warten, bis der Prozess beendet wird. Wenn der zugeordnete Prozess nicht durch das Ende des Intervalls beendet wird, da die Anforderung zum Beenden verweigert wird, wird false an die aufrufende Prozedur zurückgegeben. Sie können eine negative Zahl (unendlich) für Millisekunden angeben. Und Prozess. WaitForExit (Int32) verhält sich genauso wie die WaitForExit-Überladung Wenn Sie den Prozess beenden möchten, können Sie den folgenden Code verwenden, um das zu tun: Vin Jin MSFT MSDN Community Support Feedback an uns Get oder Request Code Beispiel von Microsoft Bitte denken Sie daran Um die Antworten als Antworten zu markieren, wenn sie helfen und sie aufheben, wenn sie keine Hilfe zur Verfügung stellen. Ja, aber es ist nicht Process. WaitForExit (Int32), die nicht funktioniert. Diese Funktion funktioniert sehr gut mit vielen ausführbaren Dateien. Das Problem ist, dass diese Funktion nicht mit PsExec und einer Standardausgabeumleitung funktioniert. Seine Arbeit nur ohne Gebrauch der Umleitung oder ohne Gebrauch ein Timeout. Montag, 20. Juni 2011, 06.41 Uhr Ich bin nicht sicher, warum wollen Sie mit keywork und warum wollen Sie nur umleiten, wenn der Prozess gestartet wird Versuchen Sie den folgenden Code: Ändern Sie es als Ihre Anfrage. Es kann gut funktionieren. Hier ist das Ergebnis: Je länger die Zeit (120000) Sie einstellen, desto mehr Imformation erhalten Sie. So schlage ich vor, dass Sie die process. WaitForExit () - Methode ohne Parameter verwenden. Vielen Dank. Vin Jin MSFT MSDN Community Support Feedback an uns Get oder Request Code Beispiel von Microsoft Bitte denken Sie daran, die Antworten als Antworten zu markieren, wenn sie helfen und entfernen Sie sie, wenn sie keine Hilfe bieten. Vielen Dank für Ihre Hilfe. Wenn ich process. WaitForExit () ohne Zeit verwenden, seine Arbeit sehr gut und ich habe die komplette Ausgabe. Aber ich benutze psexec, um ein Setup-Kit remote auszuführen, kann dieses Setup den Prozess einfrieren, also muss ich ein Timeout haben und ich möchte nicht - d-Option (Dont warten, bis Prozess zu beenden), weil ich die nächsten Schritte, um nach die Einrichtung. Montag, 20. Juni 2011 um 10:01 Uhr Wie wäre es mit der Einstellung der Zeit mehr Bitte markieren Sie es als Antwort, wenn es hilft, Ihr Problem zu lösen. Mittwoch, 22. Juni 2011 07:07 Ich habe mit 300000 versucht, es ist das gleiche Verhalten. Obwohl mein Setup-Prozess weniger als 60000 Das Problem ist nicht die Timeout-Dauer. Das Problem ist, dass eine Standardausgabe Umleitung und eine Ausführung mit einem Timeout frieren den Prozess psexec (nur psexec, nicht andere.) Hallo, ich weiß, das ist ein ganz alter Post, aber ich hatte Dass der gleiche Fehler beim Ausführen eines Prozesses mit dem Combo WaitFor () 43 RedirectStandardOutput und es wird unbegrenzt hängen. Ich fand eine Lösung für mein Problem in einem Blog-Post von Lucian Wischik, MSFT. Wenn Sie havent eine Lösung gefunden haben oder jeder andere suchen, dass bestimmte Problem sollte einen Blick auf diese Adresse: Hier ist eine Kopie seines Codes grob übersetzt in C. Mittwoch, 30. November 2011 10.23 Uhr Microsoft führt eine Online-Umfrage Um Ihre Meinung über die Msdn-Website zu verstehen. Wenn Sie sich für eine Teilnahme entscheiden, wird Ihnen die Online-Umfrage präsentiert, wenn Sie die Msdn-Website verlassen. Möchten Sie teilnehmen


No comments:

Post a Comment