24498


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

[code]

    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);
    }
    
[/code]

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

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

[code]

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

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

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


CC BY-SA 3.0
2016-05-01T16:29:51.000
24497
2016-05-01T21:21:13.837
8000
question
c#
stdout/stderrの両方に大量のデータを出力するプログラムに対して、StandardOutput.ReadToEndするとハングアップする


[Process.StandardOutputプロパティの解説の項](https://msdn.microsoft.com/ja-
jp/library/system.diagnostics.process.standardoutput\(v=vs.100\).aspx#Anchor_2)などでも説明されていますが、

> var stdout = proc.StandardOutput.ReadToEnd();  
>  var stderr = proc.StandardError.ReadToEnd();

では`stdout`を読み込み完了してからしか`stderr`を読み込み開始しませんから、当然`stderr`のバッファーが溢れ得るでしょう。両者を同時に読み込み開始する必要があります。手段はいろいろありますが

[code]

    var stdout = proc.StandardOutput.ReadToEndAsync();
    var stderr = proc.StandardError.ReadToEndAsync();
    Task.WaitAll(stdout, stderr);
    Console.WriteLine("stdout: {0} chars, stderr: {1} chars", stdout.Result.Length, stderr.Result.Length);
    
[/code]

トカ？


CC BY-SA 3.0
2016-05-01T21:21:13.837
24498
2016-05-01T21:21:13.837
4236
24497
answer