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.