Monday 11 September 2017

O Processo Waitforexit Does Not Wait


NET System. Diagnostics. Processo Classe 8211 Parte 1 Process. WaitForExit e. Exited evento aren8217t working Eu pensei que eu tinha encontrado este para ser o caso, mas foi minha culpa, provavelmente o mesmo para você também. Eu examinarei o que encontrei ao explorar e solucionar esse problema. Resposta curta: se você estiver redirecionando o StandardOutput e o StandardError, use os métodos assíncronos Process. BeginErrorReadLine () e. BeginOutputReadLine () ANTES de chamar. WaitForExit () e capture a saída conectando os eventos Process. ErrorDataReceived e. OutputDataReceived. A resposta longa começa comigo usando o Visual Studio diffmerge. exe na pasta Common7IDE para comparar arquivos de texto no modo de lote. Estou apresentando um teste de regressão em um processo de lote iniciado por compilação. Eu precisava de uma ferramenta que cuspiria um arquivo de diferença de texto ao comparar dois arquivos (não um arquivo de resultado de mesclagem). WinMerge e Beyond Compare estão à minha disposição, mas eles não parecem produzir nada além de resultados mesclados (o que normalmente é o que eu quero, mas não desta vez). Minha estrutura de regressão chamará diffmerge. exe e armazenará o arquivo diff resultante para posterior revisão. Eu codifiquei o meu ProcessStartInfo Seguiu isso com o início do processo e aguardando o encerramento do processo. E aguarde espera. Isso me fez ler MSDN e cavando mais fundo no uso da classe Process. Descobri algumas informações interessantes, provavelmente deveria ter sido óbvio. Primeiro, descobri que, às vezes, funcionava o meu Diferente Processo Infantil com diferentes argumentos trabalhados, às vezes não fazia, tornando o assunto misterioso. Em segundo lugar, achei que funcionou bem quando não escrevi a saída de redirecionamento. Então, obviamente eu estava perdendo alguma coisa. Eu precisava realmente ler os Doccs da API de Processo e, assim, encontrei esse nugget: Artigo do MSDN Depois de encontrar e ler esse artigo do MSDN, entendi. O meu exemplo de código acima funcionará se o buffer StdOut ou StdError não preencher. No entanto, o que eu estava vendo era o buffer StdOut preenchendo, o processo filho foi bloqueado na próxima gravação StdOutStdError, o processo pai estava esperando infinitamente no processo filho para sair antes de ler o buffer StdOutStdError. Para mim, pareceu que o método WaitForExit e o evento Exited estão quebrados, não apanhando o processo filho, mas era meu código que estava quebrado. Eu modifiquei o código para usar os métodos assíncronos e, de repente, meus problemas desapareceram. Não há mais bloqueio, tudo funcionou como esperado. Eu usei StringBuilders como buffers para armazenar os dados recebidos nos eventos. Na parte 2, entrei em um problema com as implementações Process StdOutStdError ReadLine em torno de minhas necessidades específicas, entro em como resolvi esse problema. Tenho uma situação em que eu quero executar um arquivo e, em seguida, exclua o arquivo executável quando a execução é feito. Eu uso System. Diagnostics. Process. Start () para executar o arquivo e use. WaitForExit () para aguardar a conclusão do processo. Eu então uso File. Delete (filename) para excluir o arquivo executável. O problema é que às vezes, File. Delete falhará com o seguinte erro: Isso me leva a acreditar que, de alguma forma, o processo ainda está vivo e bloqueando o arquivo executável mesmo depois que a chamada. WaitForExit () retorna. Eu encontrei outros tópicos na rede que descrevem o mesmo comportamento, mas não encontrei nenhum que conclua com uma explicação ou solução razoável para o problema, além das sugestões de colocar o Sleep (n) após o WaitForExit (). Exemplos: Aqui está um programa de exemplo que reproduz o problema para mim. Testei tanto no Windows XP quanto no Windows 7, e ambos, eventualmente, falharam em algum momento com o mesmo erro. Observe também que o executável ss. exe é um aplicativo simples e simples de console do quotHello Worldquot. E a saída geralmente parece ser uma coisa (com quantidade variável de iterações antes da ocorrência da falha): Qualquer idéia de por que isso acontece, e se houver alguma correção para isso (além de colocar dorme no código) sexta-feira, 8 de janeiro de 2010 3 : 40 PM O motivo é que, embora o processo seja concluído, pode demorar alguns milissegundos para que o sistema operacional termine de destruí-lo. É um sistema operacional multitarefa, está tentando atender todos ao mesmo tempo. Desnecessariamente, não há como saber quando o arquivo não está mais bloqueado (presitivamente). Quando WaitForExit, você está criando um objeto de bloqueio no objeto de processo. O objeto do processo não pode ser destruído até que o bloqueio seja liberado e você não pode esperar em algo que não existe (tipo de frango e ovo). Então, a única coisa razoável que você pode fazer é continuar tentando, algo como: Marcado como resposta por Samuel Stanojevic sexta-feira, 08 de janeiro de 2010 16:20 Editado por Tergiver sexta-feira, 8 de janeiro de 2010 4:20 PM mudou para bool, loop infinito Revisão sexta-feira, 08 de janeiro de 2010 16:15 A Microsoft está realizando uma pesquisa on-line para entender sua opinião sobre o site da Msdn. Se você optar por participar, a pesquisa on-line será apresentada quando você deixar o site Msdn. Gostaria de participar Ajude-nos a melhorar o MSDN. Visite a nossa página UserVoice para enviar e votar ideias Centros Dev Recursos de aprendizagem

No comments:

Post a Comment