Maison >développement back-end >C++ >Pourquoi «ProcessStartinfo.WaitForexit ()» accroche-t-il avec un grand standardOutput, et comment puis-je le réparer?

Pourquoi «ProcessStartinfo.WaitForexit ()» accroche-t-il avec un grand standardOutput, et comment puis-je le réparer?

Patricia Arquette
Patricia Arquetteoriginal
2025-01-29 20:21:12365parcourir

Why Does `ProcessStartInfo.WaitForExit()` Hang with Large StandardOutput, and How Can I Fix It?

Dépannage ProcessStartInfo.WaitForExit() est suspendu avec une grande sortie

Lorsque vous travaillez avec ProcessStartInfo dans .NET, un grand flux de sortie standard (par exemple, 7 Mo ou plus) peut provoquer une pension indéfiniment WaitForExit(). En effet, la taille du tampon par défaut pour la sortie standard est limitée. Pour résoudre ce problème, une lecture asynchrone est nécessaire pour éviter les débordements de tampon.

L'amélioration du code suivante redirige à la fois StandardOutput et StandardError, utilisant des lectures asynchrones pour gérer efficacement les flux de sortie potentiellement importants:

<code class="language-csharp">using (Process process = new Process())
{
    // Process configuration...

    StringBuilder output = new StringBuilder();
    StringBuilder error = new StringBuilder();

    using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
    using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
    {
        process.OutputDataReceived += (sender, e) =>
        {
            if (e.Data == null)
            {
                outputWaitHandle.Set(); // Signal completion of output stream
            }
            else
            {
                output.AppendLine(e.Data);
            }
        };

        process.ErrorDataReceived += (sender, e) =>
        {
            if (e.Data == null)
            {
                errorWaitHandle.Set(); // Signal completion of error stream
            }
            else
            {
                error.AppendLine(e.Data);
            }
        };

        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        // Use a timeout to prevent indefinite waiting
        int timeoutMilliseconds = 10000; // Example: 10-second timeout

        if (process.WaitForExit(timeoutMilliseconds) &&
            outputWaitHandle.WaitOne(timeoutMilliseconds) &&
            errorWaitHandle.WaitOne(timeoutMilliseconds))
        {
            // Process completed successfully within the timeout.
            Console.WriteLine("Output:\n" + output.ToString());
            Console.WriteLine("\nError:\n" + error.ToString());
        }
        else
        {
            // Timed out.  Handle the timeout appropriately.
            Console.WriteLine("Process timed out.");
            process.Kill(); // Consider killing the process if it's unresponsive
        }
    }
}</code>

Cette solution utilise AutoResetEvent pour signaler lorsque les flux de sortie et d'erreur ont été entièrement lus, empêchant le thread principal de bloquer indéfiniment. L'ajout d'un délai d'expiration fournit un mécanisme pour gérer les situations où le processus pourrait ne pas se terminer dans un délai raisonnable. N'oubliez pas de gérer le délai d'expiration approprié, tuant potentiellement le processus pour éviter les fuites de ressources.

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:
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