Heim >Backend-Entwicklung >C++ >Warum hängt 'WaitForexit', wenn ein Prozess eine große Ausgabe erzeugt?
Fehlerbehebung ProcessStartInfo
hängt mit reichlich Ausgabe
Dieser Artikel befasst sich mit einem gemeinsamen Problem: WaitForExit
auf unbestimmte Zeit hängen, wenn ein Prozess ein großes Ausgangsvolumen mit ProcessStartInfo
erzeugt. Dies geschieht, da der interne Puffer von ProcessStartInfo
zum Umleiten von Standardausgabe- und Fehlerströmen Größenbeschränkungen aufweist. Das Warten auf den Prozess, bevor das Lesen der Ausgabe ausgelesen wird, kann zu einem Deadlock führen. Der Prozess blockiert das Schreiben in einen vollständigen Puffer und verhindert, dass er ausgeht. In ähnlicher Weise kann die Verwendung von ReadToEnd
blockieren, wenn der Prozess nicht schließt oder Fehler auf StandardError
.
Die Lösung: Asynchrones Lesen
Der Schlüssel zur Lösung dieser Lesung ist eine asynchrone Lesart. Der folgende Code zeigt diesen verbesserten Ansatz und behandelt sowohl StandardOutput
als auch StandardError
effizient:
<code class="language-csharp">using System.Diagnostics; using System.Text; using System.Threading; using System.Threading.Tasks; // ... other using statements ... Process process = new Process(); process.StartInfo.FileName = "TheProgram.exe"; process.StartInfo.Arguments = "Your arguments"; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; StringBuilder outputBuffer = new StringBuilder(); StringBuilder errorBuffer = new StringBuilder(); AutoResetEvent outputWaitHandle = new AutoResetEvent(false); AutoResetEvent errorWaitHandle = new AutoResetEvent(false); process.OutputDataReceived += (sender, e) => { if (e.Data == null) { outputWaitHandle.Set(); // Signal completion of output stream } else { outputBuffer.AppendLine(e.Data); } }; process.ErrorDataReceived += (sender, e) => { if (e.Data == null) { errorWaitHandle.Set(); // Signal completion of error stream } else { errorBuffer.AppendLine(e.Data); } }; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); // Wait for process exit and data streams with timeout if (process.WaitForExit(30000) && outputWaitHandle.WaitOne(30000) && errorWaitHandle.WaitOne(30000)) { Console.WriteLine("Process completed successfully."); Console.WriteLine("Standard Output:\n" + outputBuffer.ToString()); Console.WriteLine("\nStandard Error:\n" + errorBuffer.ToString()); } else { Console.WriteLine("Process timed out."); } // ... rest of your code ...</code>
Dieser überarbeitete Code verwendet asynchrone Ereignishandler (OutputDataReceived
und ErrorDataReceived
), um die Ausgabe- und Fehlerströme gleichzeitig zu verarbeiten, wodurch das Blockieren verhindert wird. AutoResetEvent
Signale werden verwendet, um anzugeben, wann jeder Stream fertig ist. Eine Zeitüberschreitung ist in WaitForExit
und WaitOne
enthalten, um unbestimmte Hänge zu verhindern. Dies gewährleistet eine robuste Handhabung großer Ausgangsströme.
Das obige ist der detaillierte Inhalt vonWarum hängt 'WaitForexit', wenn ein Prozess eine große Ausgabe erzeugt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!