解决 ProcessStartInfo.WaitForExit() 在重定向标准输出或标准错误时卡住的问题
当通过 ProcessStartInfo 重定向 StandardOutput 或 StandardError 时,可能会出现问题。内部缓冲区可能会溢出,导致潜在的死锁或阻塞您的进程。
为了防止此类死锁并从两个流中收集输出,请考虑使用以下异步读取方法:
<code class="language-csharp">using System.Diagnostics; using System.Text; using System.Threading; class Program { static void Main(string[] args) { string filename = "TheProgram.exe"; string arguments = "some arguments"; int timeout = 10000; // 10 秒超时 using (Process process = new Process()) { process.StartInfo.FileName = filename; process.StartInfo.Arguments = arguments; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; 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(); } else { output.AppendLine(e.Data); } }; process.ErrorDataReceived += (sender, e) => { if (e.Data == null) { errorWaitHandle.Set(); } else { error.AppendLine(e.Data); } }; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); if (process.WaitForExit(timeout) && outputWaitHandle.WaitOne(timeout) && errorWaitHandle.WaitOne(timeout)) { // 进程成功完成。在此处检查 process.ExitCode。 Console.WriteLine($"输出: {output}"); Console.WriteLine($"错误: {error}"); //添加错误输出 } else { // 超时或发生错误。 Console.WriteLine("进程超时或失败。"); } } } } }</code>
这种异步方法确保缓冲区不会溢出,防止系统冻结。现在,您可以读取和收集输出,而无需担心延迟或潜在的死锁。 代码已改进,包含了错误输出的处理。
以上是为什么processstartinfo.waitforexit()在重定向标准输出或标准设备时会拖延?的详细内容。更多信息请关注PHP中文网其他相关文章!