为何缓冲区大小增至4MB时脚本挂起宿主进程且WaitForExit总返回false
缓冲区增大到4MB时脚本挂起宿主进程的原因
这是进程重定向标准输出、标准错误时的经典死锁问题,由代码调用顺序错误导致。
死锁触发逻辑
- Windows系统给进程重定向的标准输出、标准错误缓冲区默认上限为4MB,子进程往缓冲区写入的数据超过上限时,会自动阻塞等待父进程读取缓冲区内容,直到缓冲区有空余空间才会继续执行后续代码。
- 你当前的代码逻辑是先调用
WaitForExit(120*1000)等待子进程退出,之后才调用StandardOutput.ReadToEnd()、StandardError.ReadToEnd()读取缓冲区内容。当你的脚本总输出量超过4MB时,子进程会被写满的缓冲区阻塞,无法执行到退出逻辑,父进程的WaitForExit就会超时返回false,和你遇到的现象完全一致。 - 你提供的示例脚本单次输出100字节,循环51次总输出仅5KB左右,远低于4MB阈值,因此不会触发问题,当你把输出规模提升到4MB以上就会触发死锁。
修复方案
调整读取输出和等待进程退出的顺序,通过异步读取输出避免缓冲区被填满:
public void ExecuteTheScript() { try { System.Diagnostics.Process pProc = new System.Diagnostics.Process(); pProc.StartInfo.FileName = scriptPath; pProc.StartInfo.Arguments = scriptArguments; pProc.StartInfo.UseShellExecute = false; pProc.StartInfo.RedirectStandardOutput = true; pProc.StartInfo.RedirectStandardError = true; pProc.StartInfo.WorkingDirectory = Path.GetDirectoryName(scriptPath); // 注册异步输出接收事件,及时读取缓冲区内容 StringBuilder stdOutBuilder = new StringBuilder(); StringBuilder stdErrBuilder = new StringBuilder(); pProc.OutputDataReceived += (sender, e) => { if (e.Data != null) stdOutBuilder.AppendLine(e.Data); }; pProc.ErrorDataReceived += (sender, e) => { if (e.Data != null) stdErrBuilder.AppendLine(e.Data); }; pProc.Start(); // 启动异步读取 pProc.BeginOutputReadLine(); pProc.BeginErrorReadLine(); DateTime startTime = pProc.StartTime; bool bHasExited = pProc.WaitForExit(120 * 1000); int timeElapsed = (int)(DateTime.Now - startTime).TotalSeconds; if (timeElapsed >= timeoutInSeconds && !bHasExited) { if (sError == null) sError = "timeout and not Exited Properly"; if (!pProc.HasExited) pProc.Kill(); bOk = false; } // 等待所有异步输出读取完成 pProc.WaitForExit(); _stdOut = stdOutBuilder.ToString(); _stdErr = stdErrBuilder.ToString(); if (pProc.ExitCode != 0) { if (sError == null) sError = pProc.ExitCode.ToString(); bOk = false; } } catch (Exception e) { if (sError == null) sError = e.Message; bOk = false; } }
修复逻辑说明
- 异步读取模式会在缓冲区有新内容时立刻读取,不会让缓冲区被填满,因此不会触发子进程阻塞逻辑。
- 额外调用无参的
WaitForExit是为了确保所有异步输出事件都处理完毕,避免丢失部分输出内容。
内容的提问来源于stack exchange,提问作者KnowledgeIsPower
相关产品推荐
相关产品推荐

