代码之家  ›  专栏  ›  技术社区  ›  Lasse V. Karlsen

当从C#通过进程类生成程序时,处理标准错误和程序输出的正确方法?

  •  7
  • Lasse V. Karlsen  · 技术社区  · 14 年前

    我看了文件 Process.StandardOutput ,其中包含以下引用:

    所以我想知道。如果我还担心在某些情况下可以填充标准错误,那么正确的方法是什么?

    string error = proc.StandardError.ReadToEnd();
    string output = proc.StandardOutput.ReadToEnd();
    bool didFinish = proc.WaitForExit(60000);
    

    在发布一些答案后编辑

    所以这是正确的方法?

    var output = new StringBuilder();
    proc.OutputDataReceived += (s, e) => output.Append(e.Data);
    proc.BeginOutputReadLine();
    string error = proc.StandardError.ReadToEnd();
    bool didFinish = proc.WaitForExit(60000);
    

    然后我只在流程实际完成时才使用stringbuilder内容。

    那么这是正确的方法吗?

    2 回复  |  直到 14 年前
        1
  •  7
  •   CodingGorilla    14 年前

    您的示例代码可能会导致死锁情况,其中写入了 StandardOutput StandardError . 下一个例子来自你链接的文档。

    本质上,我建议使用两个流上的异步读取在流被写入时填充缓冲区,然后调用 WaitForExit

        2
  •  3
  •   Tim Robinson    14 年前

    出现此问题的原因是子进程将其标准输出和标准错误写入一对管道中,操作系统为这对管道提供有限的缓冲区。如果父母不积极地阅读这两本书,他们很可能会填饱肚子。当管道填满时,对它的任何后续写入都将被阻止。

    StandardError 那么所有的 StandardOutput 标准误差 和/或 . 如果子进程希望将大量数据写入 . 当父进程正在等待使用来自 ,子进程正忙于填充 标准输出

    最安全的方法是同时读取标准输入和标准错误。有几种方法可以做到这一点:

    • 生成单独的线程并调用 ReadToEnd
    • 使用 BeginRead EndRead 一根线上
    • Process.ErrorDataReceived Process.OutputDataReceived Process.BeginErrorReadLine Process.BeginOutputReadLine .