In Console Application, Windows 10, Visual Studio 2015. NET 4.6 Ich rufe einzelne Methode in Main namens TestProcess. Build-Modus Debug, wenn ich App ohne Debugging es druckt korrekten Text: Drücken Sie eine beliebige Taste, um fortzufahren. Wenn ich app mit debugging es wartet für 3 Sekunden vor dem Drucken Fehler falsch falsch false Dies ist nur Vereinfachung der realen Problem, ist dieser Code Rückgrat von einigen komplexen Code, der auch in Release ohne Debugging für md5sums. exe hängt, aber funktioniert für einige andere Programme. Coplex-Code hängt auch auf var ein proc. WaitForExit (Timeout) bis Timeout wie im beigefügten Beispiel. Auf der anderen Seite wird diese Vereinfachung in Release ohne Debugger funktionieren. Auch all diese Probleme begannen mit Windows 10, auf Windows 7 alles funktionierte gut. EDIT Cant verstehen, warum md5sums. exe Probleme verursachen würde, und wenn ich etwas anderes nasse. FileName Ping, Argumente localhost alles funktioniert wie erwartet. EDIT2 Mein komplexes Programm hörte auf, an Windows 10 zu arbeiten (Release - Run ohne Debugging), aber dieses Beispiel hängt auch unter Windows 7 (Debug - Run with debugging) gefragt am 17 Mai 16 um 13:21 Dieses Problem hat eine sehr einfache Lösung. Sie können es immer nur entdecken, wenn Sie eine aussagekräftige Fehlermeldung schreiben, eine, die dem Benutzer von Ihrem Programm einen guten Hinweis gibt, was genau schief gelaufen ist. Eine gute Faustregel ist nicht immer ein Timeout weniger als 10 Sekunden auf einem Arbeitsplatz PC, 20 Sekunden auf einem Server. Fügen Sie mehr hinzu, wenn es ein quotcomplexquot Programm ist. Ndash Hans Passant Mai 17 16 at 14:01 HansPassant Complex Programm hat Zeitüberschreitung in Tagen :) 20 Sek. Zeitüberschreitung hat das Verhalten für dieses Beispiel geändert, obwohl test. txt mit nur einer kurzen Textzeile und der Konsole. WriteLine (quotError: 39) Datei ist 39, 39 39quot) zurückgegebenError: 3939, 3939. a, b und c sind alle falsch, wenn es scheitert. Was wäre sinnvolle Fehlermeldung ndash watbywbarif Es gab 3 Fänge, dies zu lösen: md5sums. exe in einigen Fällen Pausen Ausführung nach beendet, wenn mit meinen Einstellungen gestartet: Drücken Sie ENTER zu beenden Dies kann beobachtet werden, wenn CreateNoWindow ist Auf false und stdout gesetzt, stderr-Umleitung entfernt. Dies kann durch die Verwendung von - e Schalter behoben werden: Beenden Sie sofort nicht Pause vor der Rückkehr. Dies wird alle Fälle zu beheben. Aber da habe ich nicht - ich hatte inkonsistentes Verhalten je nach Debugger und Windows-Version. Beim Laufen ohne Debugging wurde die Pause nicht ausgelöst, obwohl alle Einstellungen gleich waren und ENTER drücken, um zu beenden, wurde nicht ausgegeben. Aber das Ausführen mit Debugging verursacht Pause zu blockieren Programm bis Timeout, wo md5sums hängen in Task-Manager wartet auf Enter. Im Release-Modus laufen ohne Debugging, obwohl Pause gefeuert und drücken Sie ENTER, um zu beenden wurde in der Ausgabe auf Windows 7 md5sums zurückgegeben und Ausführung fortgesetzt, ohne zu blockieren und schlagen Timeout. Dieses war nicht Fall unter Windows 10, in dem md5sums in der Taskmanager-Wartezeit für Enter leben und das Programm fortfuhr, nachdem es Zeitüberschreitung geschlagen hatte. Antwortete 18. Mai 16 um 11: 16Der Code sieht fast so aus: Wie Sie sehen können, startet der Code einen cmd. exe Prozess und übergibt ihm den Befehl, den ich ausgeführt werden möchte. Ich leite standardError und StandarOutput um, um sie aus dem Code zu lesen. Der Code liest sie vor dem Prozess. WaitForExit (Timeout) Aufruf, wie von Microsoft empfohlen (mehr dazu später). Das Problem entsteht, wenn der Befehl, den ich an cmd. exe sendet, niemals endet oder hängt unendlich. In dem Code habe ich den Befehl ping - t 8.8.8.8 verwendet, der wegen der Option - t den Host ohne Stopp pingt. Was passiert Der cmd. exe Prozess zusammen mit dem ping - t Befehl nie beendet und nie schließt den Stdout-Stream und so unser Code hängt an der Ausgabe process. StandardOutput. ReadToEnd () Zeile, weil es nicht erfolgreich sein kann, den gesamten Stream zu lesen. Das gleiche passiert auch, wenn ein Befehl in einer Batch-Datei aus irgendeinem Grund hängt und so der obige Code könnte kontinuierlich arbeiten für Jahre und dann hängen plötzlich ohne ersichtlichen Grund. Bevor ich schrieb, dass es empfohlen ist, umgeleitete Ströme vor dem Prozess zu lesen. WaitForExit (Timeout) Aufruf, das gilt besonders, wenn Sie die WaitForExit Signatur ohne Timeout verwenden. Wenn Sie Prozess anrufen. WaitForExit (), bevor Sie die umgeleiteten Datenströme lesen: code 2: Sie können einen Deadlock erleben, wenn der Befehl, den Sie an cmd. exe anhängen, oder der Prozess, den Sie aufrufen, die Standardausgabe oder Standardfehler erfüllt. Dies, weil unser Code kann nicht erreichen die Linien Ausgabe Prozess. StandardOutput. ReadToEnd () In der Tat ist das Kind-Prozess (der Ping-Befehl oder eine Batch-Datei oder was auch immer Prozess, den Sie ausführen) kann nicht weitergehen, wenn unser Programm nicht die gefüllten Puffer der Streams liest und das kann nicht passieren, weil der Code hängt Die Linie mit dem Prozess. WaitForExit (), die immer warten wird, bis das untergeordnete Projekt beendet wird. Die Standardgröße für beide Streams beträgt 4096 Byte. Sie können diese beiden Größen mit diesen Batchdateien testen: Das erste Skript schreibt 4096 Byte zur Standardausgabe und das zweite zu Standardfehler. Sparen Sie eine davon in C: testbuffsize. bat und führen Sie unseren Programmaufrufprozess aus. WaitForExit () vor Ausgabevorgang. StandardOutput. ReadToEnd () wie in Code 2. Sie können es tun, schreiben Sie CommandResult Ergebnis ExecuteShellCommandSync (c: testbuffsize. bat, 1000) an Zeile 13 von Code 1. Der Code wird nicht hängen, aber wenn Sie ein weiteres Byte in einem der beiden Streams schreiben, wird es die Puffergröße überlaufen, die das Programm macht aufhängen. Wenn Sie die Standardausgabe oder Standardfehler umleiten und lesen müssen, ist die beste Lösung, sie asynchron zu lesen. Eine hervorragende Möglichkeit, dies zu tun, wird von Mark Byers in diesem Stackoverflow-Thread vorgeschlagen. Als letztes Ding bemerken Sie bitte, dass, wenn das Kind-Prozess beendet, nur weil Sie den Prozess verwenden. WaitForExit (Timeout) Signatur und es geht eigentlich in Timeout Sie sollten den cmd. exe Prozess und seine möglichen Kinder zu töten.
No comments:
Post a Comment