Por que o método Exited do meu processo não está sendo chamado?


96

Eu tenho o seguinte código, mas por que o ProcessExitedmétodo nunca é chamado? É o mesmo se eu não usar o shell do 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
}

Respostas:


241

Para receber um retorno de chamada no Exitedevento, o EnableRaisingEventsdeve ser definido como verdadeiro.

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

3
correctProcess.WaitForExit (), sem esta função este código não funciona para mim
— Kira

7
Uma pequena dica (especialmente para não especialistas em C #): não Close()opere! Encontrei problemas intermitentes com o manipulador de saída devido a um esforço equivocado no gerenciamento de recursos. O código em questão foi chamado Process.Close()depois Process.Start(startInfo), em vez de permitir que o GC o coletasse no devido tempo. Erro fácil se seu plano de fundo for de linguagens não GC (por exemplo, C / C ++).
— Jerzy

3
Ótimo. Obrigado. Também quero ressaltar que a atribuição de EnableRaisingEventse EventHandlersdeve ser feita exatamente após o Process.Start(). Não vai funcionar de outra forma.
— Doruk,

2
@Doruk posso definir EnableRaisingEvents=trueantes de ligar Process.Start()e funciona bem.
— Ação Dan de

29

Do MSDN :

O evento Exited indica que o processo associado foi encerrado. Esta ocorrência significa que o processo foi encerrado (abortado) ou fechado com sucesso. Este evento só poderá ocorrer se o valor da propriedade EnableRaisingEvents for verdadeiro.

Você definiu essa propriedade como verdadeira?


19
É uma bandeira muito pouco idomática (de que adianta, se eu não quiser o evento, não me inscrevo!)
— Tamás Szelei

3
Não é muito intuitivo. Deve indicar claramente em cada descrição de evento que requer que este sinalizador seja definido.
— TheLegendaryCopyCoder

18

Você deve definir Process.EnableRaisingEventspara true.



9

Encontrei exemplos que aparecem new Process()em uma usingcláusula. Não faça isso se quiser usar o Exitedrecurso. A usingcláusula destrói a instância junto com qualquer identificador de evento emExited .

Este...

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

Deve ser isso ...

var process = new Process();

Eu também percebi isso. Estranhamente, os eventos OutputDataReceived funcionam bem. Ou podem ocorrer tão rápido que vão antes da execução no thread principal chegar ao Fim do Uso.
— AlexVB
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.