stdout/stderrの両方に出力するプログラムからそれぞれの出力を取り出すため、以下のようなプログラムを書きました。

var startInfo = new ProcessStartInfo
{
    FileName = @"TestApp.exe",
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardError = true,
    CreateNoWindow = true
};

using (var proc = Process.Start(startInfo))
{
    var stdout = proc.StandardOutput.ReadToEnd();
    var stderr = proc.StandardError.ReadToEnd();
    Console.WriteLine("stdout: {0} chars, stderr: {1} chars", stdout.Length, stderr.Length);
}

これで最初のうちは上手くいっていたのですが、どうも出力が一定量を超える場合にハングアップしてしまうようなのです。もちろんコマンドプロンプトで実行すれば一瞬で出力が終わります。

例えば、以下のプログラムを前述の TestApp.exe とするとこの問題が起きます。

static void Main(string[] args)
{
    for (int i = 0; i < 100; ++i)
    {
        // ピリオドの数を半分にすれば問題なく動く
        Console.WriteLine("STDOUT: .................... {0}", i);
        Console.Error.WriteLine("STDERR: .................... {0}", i);
    }
}

両方とも ReadToEnd() を使っているのがまずいのではと思い、RedirectStandardError = trueproc.StandardError.ReadToEnd() を取り除いてみましたが、同じようにハングアップしてしまいます。

このようなプログラムから出力を読み取るにはどうしたらよいのでしょうか?