2012-02-28 25 views
8

私は手動で実行すると正常に動作する実行可能ファイルを持っています。しかし、私が以下のメソッドでそれを実行すると、Process.Exitedイベントは決して起動されません。私はexitイベントを待つために、代わりに反応性の拡張機能のProcess.WaitForExitを()を使用する場合の問題は、同じであるProcess.EnableRaisingEventsEnableRaisingEventsがtrueに設定されていても、Process.Exitedは呼び出されません

protected override Result Execute(RunExecutable task) 
{ 
    var process = new Process(); 
    process.StartInfo.Arguments = task.Arguments; 
    process.StartInfo.FileName = task.ExecutablePath; 
    process.StartInfo.CreateNoWindow = true; 
    process.StartInfo.UseShellExecute = false; 
    process.StartInfo.RedirectStandardOutput = true; 
    process.EnableRaisingEvents = true; 

    process.Exited += (sender, args) => 
    { 
     processSync.OnNext(new Result 
     { 
      Success = process.ExitCode == 0, 
      Message = process.StandardOutput.ReadToEnd() 
     }); 
     processSync.OnCompleted(); 
    }; 
    process.Start(); 

    return processSync.First();; 
} 

を覚えていることに注意してください。

また、別の出力を生成する別の引数を使用してプロセスを実行すると、正常に存在します。

これを無効にすると、それが機能するので、process.StartInfo.RedirectStandardOutput = true;と何か関係があるようです。しかし、それはちょうど別の問題の症状かもしれません。

助けを歓迎します:-)

答えて

6

コードにデッドロックがあります。 '標準出力'は名前付きパイプの一種であり、あるプロセスから別のプロセスにデータを転送する小さなバッファを持っています。バッファがいっぱいである場合、書き込みプロセスは、読み出しプロセスがバッファからいくつかのデータを取り出すのを待たなければならない。

開始したプロセスが標準出力から読み込むのを待つかもしれませんが、読み込みを開始する前にプロセスが終了するのを待っています - >デッドロックです。

解決方法は、プロセスが実行されている間は継続的に読み取ります。WaitForExit()に電話する前にStandardOutput.ReadToEnd()に電話するだけです。 現在のスレッドをブロックせずに読み込みたい場合は、BeginOutputReadLine()OutputDataReceivedのイベントを使用できます。

+0

アー!ありがとう:-) –

1

リダイレクトした場合は、StandardOutputストリームを聞く必要があります。そうしないと、プロセスは終了しません。誰かが最初に出力を読むのを待ちます。

Process.Exited event is not be called

関連する問題