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