3

(新しいプロセスで)「コンソール」アプリケーションを実行し、出力を解析するGUIアプリケーションがあります。出力をリダイレクトするには、pConsole.StartInfo.RedirectStandardOutput を true に設定します。イベント pConsole.Exited にも登録しています。

問題は、Exited イベント ハンドラで Thread.Sleep() を使用して最後のデータを取得する必要があることです。

私の Exited イベント ハンドラーは次のようになります。

Thread.Sleep(100); // Wait for additional data (if any).
pConsole.OutputDataReceived -= new System.Diagnostics.DataReceivedEventHandler(this.localTerminal_DataAvailableEvent);
int exit = pConsole.ExitCode;
pConsole.Dispose();
pConsole = null;

Exited イベントは、最後の pConsole_DataAvailableEvent の前に実行されるようです。誰がどのように/なぜこれが起こっているのか知っていますか?

また、ミューテックス/ロックを使用して、次のコンソール アプリケーションの実行を開始する前に、Exited イベントが終了していることを確認します。

4

4 に答える 4

3

問題はほぼ確実に出力バッファリングです。プロセスは終了し、Exited イベントをトリガーしますが、一部の出力データはまだバッファ内にあります。あなたのハックはおそらくうまくいく場合もありますが、他のアプローチの方がより堅牢かもしれません。検討:

1) Exited イベント ハンドラーを削除し、代わりに OutputDataReceived ハンドラーで Process.HasExited を確認します。

2) OutputDataReceived ハンドラーを使用せず、Process.StandardOutput ストリームで Read() を呼び出します。ストリームが閉じられたら、後処理のクリーンアップを実行します。

于 2008-11-03T18:06:58.157 に答える
2

それがより良いかどうかはわかりませんが、以下のように、スレッドを使用して stderr/stdout の両方を読み取る同様のものを見てきました。(デッドロックや複雑な非同期コードを回避するために) いくつかの余分なスレッドが必要ですが、かなり安定して動作するようです。

ここで重要なのは、I Join()/O を処理する 2 つのスレッドで、両方の出力ストリームが完全に消費されてから先に進むことです。

            using (Process proc = Process.Start(psi))
            {
                Thread stdErr = new Thread(DumpStream(proc.StandardError, Console.Error));
                Thread stdOut = new Thread(DumpStream(proc.StandardOutput, Console.Out));
                stdErr.Name = "stderr reader";
                stdOut.Name = "stdout reader";
                stdErr.Start();
                stdOut.Start();
                proc.WaitForExit();
                stdOut.Join();
                stdErr.Join();
                if (proc.ExitCode != 0) {...} // etc
            }

    static ThreadStart DumpStream(TextReader reader, TextWriter writer)
    {
        return (ThreadStart) delegate
         {
             string line;
             while ((line = reader.ReadLine()) != null) writer.WriteLine(line);
         };
    }
于 2008-11-03T11:31:57.190 に答える
1

オペレーティングシステムが出力バッファをフラッシュしているだけだと強く思います。あなたの回避策は問題ないように見えますが、明らかに醜い (あなたのせいではありません) し、場合によっては睡眠の長さが無駄に長くなり、他の病的な場合には十分に長くない可能性があります。

于 2008-11-03T11:09:44.957 に答える
0

Marc Gravellの答えに加えて

proc.StandardError、proc.StandardOutput の両方に EndOfStream メソッドがあります。これは、ユーザー入力/プロンプトの前に出力が改行を生成しない場合を判断するのに役立ちます

于 2011-01-04T09:27:53.670 に答える