C Padrão Saída Esperaforexit Doesnt Wait


Eu uso Process. Start para iniciar um arquivo em lote. O arquivo em lote usa o comando START para iniciar vários programas em paralelo e depois sai. Uma vez que o arquivo em lotes é concluído Process. HasExited torna-se verdadeiro e Process. ExitCode contém o código de saída correto. Mas quando chamo Process. WaitForExit (), ele trava nunca retorna. O código a seguir demonstra o problema. Ele cria um arquivo em lotes, o inicia e depois imprime: Ele deve imprimir: mas nunca o faz (mesmo que HasExited seja verdadeiro e já temos um ExitCode). Notei que isso só ocorre quando o arquivo em lotes contém comandos START e quando a saída padrão e o erro padrão são redirecionados. Por que WaitForExit () nunca retorna O que é o caminho certo para aguardar o encerramento de um processo desse tipo É seguro apenas pesquisar Process. HasExited ou pode resultar em outros problemas PS. Acabei de notar que chamar WaitForExit (100000) com um tempo limite enorme (que definitivamente não expira) retorna imediatamente quando o processo sai. Wierd. Sem tempo limite, ele trava. Existe uma diferença fundamental quando você chama WaitForExit () sem tempo limite, ele garante que o stdouterr redirecionado tenha retornado EOF. Isso garante que você tenha lido toda a saída que foi produzida pelo processo. Nós não podemos ver o que o quotonOutputquot faz, mas as chances de que ele impede o seu programa porque ele faz algo desagradável como assumir que seu segmento principal está ocioso quando ele está realmente preso em WaitForExit (). Ndash Hans Passant 3 nov 14 às 12:06 Isso parece ser um artefato (Id say bug) na implementação específica do tratamento assíncrono baseado em eventos do StandardOutput e do StandardError. Percebi que, enquanto consegui reproduzir facilmente o seu problema, simplesmente executando o código que você forneceu (excelente exemplo de código, a propósito.)), O processo realmente não era suspenso indefinidamente. Em vez disso, ele retornou de WaitForExit () uma vez que ambos os processos filho que tinham sido iniciados já haviam saído. Isso parece ser uma parte intencional da implementação da classe Process. Em particular, no método Process. WaitForExit (), uma vez que terminou de aguardar o processo, ele verifica se um leitor para stdout ou stderr foi criado se assim for, e se o valor de tempo limite para o WaitForExit ( ) Chamada é infinita (ou seja, -1), o código realmente espera o fim do fluxo no (s) leitor (es). Cada leitor respectivo é criado somente quando o método BeginOutputReadLine () ou BeginErrorReadLine () é chamado. Os fluxos stdout e stderr não estão fechados até que os processos filho tenham fechado. Então, esperando no final desses fluxos irá bloquear até que isso aconteça. Que WaitForExit () deve se comportar de forma diferente, dependendo se um tenha chamado qualquer um dos métodos que iniciam a leitura baseada em eventos dos fluxos ou não, e especialmente porque a leitura desses fluxos diretamente não causa WaitForExit () para comportar-se desse jeito, cria Uma inconsistência na API que torna muito mais difícil de entender e usar. Enquanto eu pessoalmente chamo isso de bug, suponho que é possível que o implementador (es) da classe Process esteja ciente dessa inconsistência e criou isso de propósito. Em qualquer caso, o trabalho seria ler StandardOutput e StandardError diretamente em vez de usar a parte baseada em eventos da API. (Embora, é claro, se o código estivesse esperando nesses fluxos, verificaria o mesmo comportamento de bloqueio até que o filho fique próximo). Por exemplo (C, porque eu não conheço F bem o suficiente para tapar um exemplo de código assim juntado rapidamente :)): Espero que o trabalho acima ou algo semelhante abordará o problema básico em que você se encontrou. Meus agradecimentos ao comentarista Niels Vorgaard Christensen por dirigir-me para as linhas problemáticas no método WaitForExit (), para que eu possa melhorar esta resposta. Com base no meu entendimento, o método Process. WaitForExit (int32) não significa sair quando o tempo limite. A sobrecarga WaitForExit (Int32) é usada para fazer o thread atual aguardar até o processo associado terminar. Essa sobrecarga instrui o componente Processo a aguardar uma quantidade limitada de tempo para o processo sair. Se o processo associado não sair pelo final do intervalo porque a solicitação de término é negada, falso é retornado ao procedimento de chamada. Você pode especificar um número negativo (Infinito) por milissegundos. E Processo. WaitForExit (Int32) irá comportar-se da mesma forma que a sobrecarga WaitForExit Se você quiser fechar o processo, você pode usar o seguinte código para fazer o que quiser: Vin Jin MSFT MSDN Community Support Feedback para nós Obter ou solicitar um exemplo de código da Microsoft Lembre-se Para marcar as respostas como respostas se elas ajudam e desmarcá-las se não fornecem ajuda. Segunda-feira, 20 de junho de 2011 6:26 Sim, mas não é Process. WaitForExit (Int32) que não funciona. Esta função funciona muito bem com muitos executáveis. O problema é que esta função não funciona com o PsExec e um redirecionamento de saída padrão. Seu trabalho somente sem usar o redirecionamento ou sem usar um tempo limite. Segunda-feira, 20 de junho de 2011 6:41 AM Não tenho certeza por que você quer usar o trabalho de chave e por que você deseja redirecionar somente quando o processo for iniciado. Tente o seguinte código: Para modificá-lo como seu pedido. Pode funcionar bem. Aqui está o resultado: quanto mais tempo (120000) você definir, mais informações você receberá. Então sugiro que use o método process. WaitForExit () sem parâmetros. Obrigado. Vin Jin MSFT Suporte Comunidade MSDN Feedback para nós Obtenha ou solicite um exemplo de código da Microsoft Lembre-se de marcar as respostas como respostas se elas ajudarem e desmarcar se não fornecem ajuda. Segunda-feira, 20 de junho de 2011 9:42 AM Obrigado pela sua ajuda. Se eu usar process. WaitForExit () sem tempo, funciona muito bem e eu tenho a saída completa. Mas eu uso o psexec para executar um kit de instalação remotamente, esta configuração pode congelar o processo, então eu preciso ter um tempo limite e não quero usar a opção - d (não espere que o processo termine) porque eu tenho os próximos passos para executar depois A configuração. Segunda-feira, 20 de junho de 2011 10:01 AM Sobre como ajustar o tempo mais longo Por favor, marque como resposta, se isso ajuda a resolver seu problema. Quarta-feira, 22 de junho de 2011 7:07 AM Eu tentei com 300000, é o mesmo comportamento. Embora meu processo de instalação demore menos de 60000. O problema não é a duração do tempo limite. O problema é que um redirecionamento de saída padrão e uma execução com um tempo limite congelam o processo psexec (apenas psexec, e não outro.) Quarta-feira, 22 de junho de 2011 7:19 AM Oi, eu sei que isso é uma postagem antiga, mas eu tinha O mesmo erro ao tentar executar um processo usando o Combo WaitFor () 43 RedirectStandardOutput e ele irá pendurar indefinidamente. Encontrei uma solução para o meu problema em uma postagem no blog de Lucian Wischik, MSFT. Se você não encontrou uma solução, ou qualquer outra pessoa que pesquisasse esse problema específico deveria dar uma olhada neste endereço: Aqui está uma cópia do código dele traduzida em C. quarta-feira, 30 de novembro de 2011 22:23 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. Você gostaria de participar

Comments

Popular Posts