首頁 > 後端開發 > 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
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板