首页 > 后端开发 > C++ > 为什么WaitForexit失速使用大型数据流将标准输出重定向时?

为什么WaitForexit失速使用大型数据流将标准输出重定向时?

Susan Sarandon
发布: 2025-01-29 20:42:09
原创
915 人浏览过

Why Does WaitForExit Stall When Redirecting Standard Output with Large Data Streams?

处理大型数据流标准输出重定向时WaitForExit挂起的问题

通过ProcessStartInfo执行进程时,可能会遇到与StandardOutput缓冲区限制相关的问题。具体来说,当重定向StandardOutput时,如果输出大小超过某个阈值(例如7MB),程序可能会在WaitForExit期间无限期挂起。

原因

当重定向StandardOutput且内部缓冲区已满时,就会发生此行为。如果调用进程在读取StandardOutput之前等待目标进程退出,则目标进程在尝试写入已满的缓冲区时会被阻塞,从而阻止其结束。相反,如果调用进程使用ReadToEnd检索输出,则如果目标进程不关闭StandardOutput(例如,如果它不终止或其StandardError流被阻塞),它可能会被阻塞。

解决方案

为了解决这个问题,请使用异步读取以防止缓冲区达到容量。以下代码示例演示了如何执行此操作:

<code class="language-csharp">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。
        }
        else
        {
            // 超时。
        }
    }
}</code>
登录后复制

此解决方案使用异步回调来处理从StandardOutputStandardError接收到的数据,确保内部缓冲区不会满并防止死锁。

注意:为了避免在发生超时时出现ObjectDisposedException,请在访问进程的输出或错误流之前检查进程的HasExited属性。

以上是为什么WaitForexit失速使用大型数据流将标准输出重定向时?的详细内容。更多信息请关注PHP中文网其他相关文章!

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