Heim >Backend-Entwicklung >C++ >Warum hängt 'WaitForexit', wenn ein Prozess eine große Ausgabe erzeugt?

Warum hängt 'WaitForexit', wenn ein Prozess eine große Ausgabe erzeugt?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2025-01-29 20:16:10628Durchsuche

Why Does `WaitForExit` Hang When a Process Generates Large Output?

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.

stößt

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn