2012-02-28 13 views
8

Tengo un ejecutable, que funciona bien cuando lo ejecuto manualmente, y existe como debería con el resultado esperado. Pero cuando lo ejecuto con el siguiente método, el evento Process.Exited nunca se activa. Tenga en cuenta que me he acordado de las Process.EnableRaisingEventsProcess.Exited nunca se llama, aunque EnableRaisingEvents está establecido en verdadero

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();; 
} 

El problema es el mismo, si yo uso Process.WaitForExit() en lugar de extensiones de reactivos, a esperar a que el evento de salida.

Además, si ejecuto el proceso con otro argumento, que produce otro resultado, existe bien.

Parece tener algo que ver con el process.StartInfo.RedirectStandardOutput = true; ya que cuando desactivo esto, funciona. Pero eso podría ser solo un síntoma de otro problema.

Cualquier ayuda es apreciada :-)

Respuesta

6

Hay un punto muerto en el código. 'Salida estándar' es solo un tipo de tubería con nombre, que tiene un pequeño buffer para transferir datos de un proceso a otro. Si el búfer está lleno, el proceso de escritura tiene que esperar a que el proceso de lectura recupere algunos datos del búfer.

Así que el proceso que ha comenzado puede esperar a que lea desde la salida estándar, pero está esperando que el proceso termine antes de comenzar la lectura -> interbloqueo.

La solución es leer de forma continua mientras el proceso se está ejecutando; simplemente llame al StandardOutput.ReadToEnd() antes de llamar al WaitForExit(). Si quiere leer sin bloquear el hilo actual, puede usar los eventos BeginOutputReadLine() y OutputDataReceived.

+0

Arh, eso lo explica! Gracias :-) –

1

Aparentemente debe escuchar la transmisión StandardOutput si la redirigió, de lo contrario, el proceso no finalizará. Espera a que alguien lea la salida primero.

Process.Exited event is not be called

Cuestiones relacionadas