Почему не вызывается метод Exited моего процесса?


96

У меня есть следующий код, но почему ProcessExitedметод никогда не вызывается ? То же самое, если я не использую оболочку 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
}

Ответы:


241

Чтобы получить обратный вызов при Exitedсобытии, EnableRaisingEventsнеобходимо установить значение true.

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

3
CorrectionProcess.WaitForExit (), без этой функции этот код у меня не работает
— Кира

7
Один небольшой совет (особенно для не экспертов по C #): не Close()используйте процесс! Я столкнулся с периодически возникающей проблемой с обработчиком выхода из-за неправильного управления ресурсами. Рассматриваемый код вызывается Process.Close()после Process.Start(startInfo), а не позволяет GC собирать его в должное время. Легкая ошибка, если ваш опыт работы с языками, отличными от GC (например, C / C ++).
— Ежи

3
Отлично. Спасибо. Также хочу отметить, что присвоение EnableRaisingEventsи EventHandlersдолжно выполняться именно после Process.Start(). Иначе не пойдет.
— Дорук

2
@Doruk я могу установить EnableRaisingEvents=trueперед звонком, Process.Start()и он отлично работает.
— Action Dan

29

Из MSDN :

Событие Exited указывает, что связанный процесс завершился. Это событие означает, что процесс завершен (прерван) или успешно закрыт. Это событие может произойти, только если значение свойства EnableRaisingEvents равно true.

Вы установили для этого свойства значение true?


19
Это тоже очень неидоматический флаг (в любом случае, какой толк, если я не хочу этого события, я не подписываюсь на него!)
— Тамаш Селей

3
Не очень интуитивно понятно. В описании каждого события должно быть четко указано, что этот флаг должен быть установлен.
— TheLegendaryCopyCoder



10

Я встречал примеры, которые помещаются new Process()в usingпредложения. Не делайте этого, если хотите использовать эту Exitedфункцию. Предложение usingуничтожает экземпляр вместе с любыми обработчиками событий Exited.

Это...

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

Должно быть это ...

var process = new Process();

Я тоже это заметил. Как ни странно, события OutputDataReceived работают нормально. Или, может быть, они происходят так быстро, что выполняются до того, как выполнение в основном потоке дойдет до End Using.
— AlexVB 08
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.