首页 > 后端开发 > C++ > 当一个过程产生大输出时,为什么``wareforexit'''悬挂?

当一个过程产生大输出时,为什么``wareforexit'''悬挂?

Mary-Kate Olsen
发布: 2025-01-29 20:16:10
原创
589 人浏览过

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

> 故障排除ProcessStartInfo悬挂着丰富的输出

>

>本文解决了一个常见的问题:WaitForExit使用ProcessStartInfo生成大量输出时,无限期地悬挂。之所以发生这种情况,是因为用于重定向标准输出和错误流的内部缓冲区具有大小限制。 在阅读输出之前等待流程出口会导致僵局;该过程会阻止写入完整的缓冲区,从而阻止其退出。 同样,如果该过程未关闭或遇到写入ProcessStartInfoReadToEnd解决方案:异步读取StandardError

>

解决此问题的关键是异步阅读。 以下代码证明了这种改进的方法,同时处理>>>>>>>

此修订的代码使用异步事件处理程序(StandardOutputStandardError)同时处理输出和错误流,从而防止阻塞。

>信号用于指示每个流何时完成。
<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>
登录后复制
>和

中包含一个超时,以防止无限期悬挂。 这样可以确保对大型输出流的强大处理。OutputDataReceived

以上是当一个过程产生大输出时,为什么``wareforexit'''悬挂?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板