如何以有效的方式阅读儿童 pocress 标准中的长行

本文关键字:标准 pocress 有效 方式阅 | 更新日期: 2023-09-27 18:30:43

注意:这个问题自第一个版本以来发生了重大变化,因此一些评论或答案可能看起来很奇怪。请检查编辑历史记录,如果有什么东西看起来很奇怪。

我正在从 C# 类库启动一个子进程。

我正在使用Process.BeginOutputReadLine()以异步方式读取输出/错误。我认为它不适用于很长的行,但问题似乎是它不可扩展。在我的电脑中,一行 128 kb 的行是即时处理的,一个 512 kb 的行似乎需要大约一分钟,1 mb 的行似乎需要几分钟,我已经等了大约两个小时等待处理 10 mb 的行,当我取消它时它仍然在工作。

直接从 StandardOutput 和 StandardError 流中修复读取似乎很容易,但来自这些流的数据似乎被缓冲了。如果我从 stdout 获取 wnough 数据来填充缓冲区,然后从 stderr 获取更多数据,我找不到一种方法来检查其中一个中是否有待处理的数据,如果我尝试从 stderr 读取,它将永远挂起。为什么会这样,我做错了什么,正确的方法是什么?

一些代码示例来说明我想要实现的目标。

Program1

    // Writes a lot of data to stdout and stderr
    static void Main(string[] args)
    {
        int numChars = 512 * 1024;
        StringBuilder sb = new StringBuilder(numChars);
        String s = "1234567890";
        for (int i = 0; i < numChars; i++)
            sb.Append(s[i % 10]);
        int len = sb.Length;
        Console.WriteLine(sb.ToString());
        Console.Error.WriteLine(sb.ToString());
    }

Program2

    // Calls Program1 and tries to read its output.
    static void Main(string[] args)
    {
       StringBuilder sb = new StringBuilder();
       StringBuilder sbErr = new StringBuilder();
       proc.StartInfo.CreateNoWindow = true;
       proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
       proc.StartInfo.UseShellExecute = false;
       proc.StartInfo.RedirectStandardError = true;
       proc.StartInfo.RedirectStandardOutput = true;
       proc.StartInfo.RedirectStandardInput = false;
       proc.StartInfo.Arguments = "";
       proc.StartInfo.FileName = "program1.exe";
       proc.ErrorDataReceived += (s, ee) => { if (ee.Data != null) sbErr.AppendLine(ee.Data); };
       proc.OutputDataReceived += (s, ee) => { if (ee.Data != null) sb.AppendLine(ee.Data); };
       proc.Start();
       proc.BeginOutputReadLine();
       proc.BeginErrorReadLine();
       proc.WaitForExit();
    }

Program1有一个常量,允许设置要生成的数据的大小,Program2启动Program1并尝试读取数据。我应该期待时间随着大小线性增长,但它似乎比这糟糕得多。

如何以有效的方式阅读儿童 pocress 标准中的长行

我希望我理解你的问题。 应用程序挂在Process.WaitForExit()上,因为这就是Process.WaitForExit():它等待进程退出。

您可能希望在新线程中调用它:int 创建流程的方法:

    Thread trd = new Thread(new ParameterizedThreadStart(Start));
     trd.Start();

并添加此方法:

  private void Start(object o)
  {
     ((Process)o).WaitForExit();
     // your code after process ended
  }