Maison > développement back-end > C++ > Pourquoi «Waitforexit» est-il suspendu lorsqu'un processus génère une grande sortie?

Pourquoi «Waitforexit» est-il suspendu lorsqu'un processus génère une grande sortie?

Mary-Kate Olsen
Libérer: 2025-01-29 20:16:10
original
627 Les gens l'ont consulté

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

Dépannage ProcessStartInfo est suspendu avec une sortie abondante

Cet article aborde un problème commun: WaitForExit suspendu indéfiniment lorsqu'un processus génère un grand volume de sortie en utilisant ProcessStartInfo. Cela se produit parce que le tampon interne de ProcessStartInfo pour la redirection de sortie standard et de flux d'erreur a des limitations de taille. Attendre la sortie du processus avant de lire la sortie peut entraîner une impasse; Le processus bloque l'écriture dans un tampon complet, l'empêchant de sortir. De même, l'utilisation de ReadToEnd peut bloquer si le processus ne se ferme pas ou rencontre des erreurs en écrivant à StandardError.

La solution: lecture asynchrone

La clé pour résoudre ceci est la lecture asynchrone. Le code suivant démontre cette approche améliorée, gérant à la fois StandardOutput et StandardError efficacement:

<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>
Copier après la connexion

Ce code révisé utilise des gestionnaires d'événements asynchrones (OutputDataReceived et ErrorDataReceived) pour traiter simultanément des flux de sortie et d'erreur, empêchant le blocage. Les signaux AutoResetEvent sont utilisés pour indiquer la fin de chaque flux. Un délai d'expiration est inclus dans WaitForExit et WaitOne pour éviter les pendus indéfinis. Cela garantit une manipulation robuste des grands flux de sortie.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal