Dlaczego metoda Exited mojego procesu nie jest wywoływana?


96

Mam następujący kod, ale dlaczego ProcessExitedmetoda nigdy nie jest wywoływana? Tak samo jest, jeśli nie używam powłoki systemu Windows ( startInfo.UseShellExecute = false).

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = path;
startInfo.Arguments = rawDataFileName;
startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);

try
{
     Process correctionProcess = Process.Start(startInfo);
     correctionProcess.Exited += new EventHandler(ProcessExited);                   

     correctionProcess.WaitForExit();

     status = true;
}

.....

internal void ProcessExited(object sender, System.EventArgs e)
{
      //print out here
}

Odpowiedzi:


241

Aby otrzymać wywołanie zwrotne w Exitedprzypadku zdarzenia, EnableRaisingEventsnależy ustawić wartość true.

Process correctionProcess = Process.Start(startInfo);
correctionProcess.EnableRaisingEvents = true;
correctionProcess.Exited += new EventHandler(ProcessExited); 

3
rectionProcess.WaitForExit (), bez tej funkcji ten kod nie działa u mnie
Kira

7
Jedna mała wskazówka (szczególnie dla osób nie znających języka C #): nie wykonuj Close()tego procesu! Napotkałem sporadyczny problem z programem obsługi wyjścia z powodu niewłaściwego zarządzania zasobami. Kod, o którym mowa, został wywołany Process.Close()później Process.Start(startInfo), zamiast pozwolić GC zebrać go w odpowiednim czasie. Łatwy błąd, jeśli twoje tło nie jest językiem GC (np. C / C ++).
Jerzy

3
Wspaniały. Dzięki. Chcę również zauważyć, że przypisanie EnableRaisingEventsi EventHandlersmusi być wykonane dokładnie po Process.Start(). Inaczej to nie zadziała.
Doruk

2
@Doruk mogę ustawić EnableRaisingEvents=trueprzed zadzwonieniem Process.Start()i działa dobrze.
Action Dan

29

Z MSDN :

Zdarzenie Exited wskazuje, że skojarzony proces zakończył działanie. To wystąpienie oznacza, że ​​proces został zakończony (przerwany) lub pomyślnie zamknięty. To zdarzenie może wystąpić tylko wtedy, gdy wartość właściwości EnableRaisingEvents jest true.

Czy ustawiłeś tę właściwość na true?


19
To też bardzo nie-idomatyczna flaga (po co mi to, jeśli nie chcę tego wydarzenia, nie subskrybuję!)
Tamás Szelei

3
Niezbyt intuicyjne. Powinien jasno określać w każdym opisie zdarzenia, że ​​wymaga ustawienia tej flagi.
TheLegendaryCopyCoder



10

Natknąłem się na przykłady, które umieszczają się new Process()w usingklauzuli. Nie rób tego, jeśli chcesz korzystać z tej Exitedfunkcji. usingKlauzula niszczy instancji wraz ze wszystkimi uchwytami na zdarzeniach Exited.

To...

using(var process = new Process())
{
   // your logic here
}

Powinien być taki ...

var process = new Process();

Też to zauważyłem. O dziwo, zdarzenia OutputDataReceived działają dobrze. A może pojawiają się tak szybko, że zanim wykonanie w głównym wątku dojdzie do końca używania.
AlexVB
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.