2012-02-28 18 views
8

Mam plik wykonywalny, który działa poprawnie, gdy uruchamiam go ręcznie, i istnieje tak jak powinien z oczekiwanym wynikiem. Ale kiedy uruchomię go za pomocą metody poniżej, zdarzenie Process.Exited nigdy nie jest uruchamiane. Zauważ, że nie pamiętał Process.EnableRaisingEventsProcess.Exited nie jest wywoływany, mimo że EnableRaisingEvents ma wartość true

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

Problem polega na tym samym, w przypadku korzystania z Process.WaitForExit() zamiast reaktywnych rozszerzeń, aby czekać na zdarzenia wyjściowego.

Również, jeśli uruchomię proces z innym argumentem, który produkuje inne wyjście, to jest w porządku.

Wydaje się, że ma to coś wspólnego z process.StartInfo.RedirectStandardOutput = true;, ponieważ po wyłączeniu tego działa. Ale to może być tylko symptom innego problemu.

Każda pomoc jest mile widziana :-)

Odpowiedz

6

Jest impas w kodzie. "Standardowe wyjście" to tylko rodzaj nazwanej rury, która ma mały bufor do przesyłania danych z jednego procesu do drugiego. Jeśli bufor jest pełny, proces zapisu musi poczekać na proces odczytu, aby pobrać niektóre dane z bufora.

Tak więc rozpoczęty proces może poczekać na odczyt ze standardowego wyjścia, ale czeka na zakończenie procesu przed rozpoczęciem odczytu -> impasu.

Rozwiązaniem jest ciągłe odczytywanie w trakcie procesu - wystarczy zadzwonić pod numer StandardOutput.ReadToEnd(), zanim zadzwonisz pod numer WaitForExit(). Jeśli chcesz przeczytać bez blokowania bieżącego wątku, możesz użyć zdarzeń BeginOutputReadLine() i OutputDataReceived.

+0

Arh, że wyjaśnia to! Dzięki :-) –

1

Podobno musisz posłuchać strumienia StandardOutput, jeśli go przekierowałeś, w przeciwnym razie proces nie zostanie zakończony. Czeka, aby ktoś najpierw odczytał wynik.

Process.Exited event is not be called

Powiązane problemy