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
Freigeben: 2025-01-29 20:16:10
Original
658 Leute haben es durchsucht

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:

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 ...
Nach dem Login kopieren

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!

Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage