Sunday, 5 November 2017

Waitforexit processed


Eu uso Process. Start para iniciar um arquivo em lotes. O arquivo em lotes usa o comando START para iniciar vários programas em paralelo e, em seguida, sai. Uma vez que o arquivo de lote é feito Process. HasExited torna-se verdadeira 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, inicia-lo e imprime: Ele deve imprimir: mas ele nunca faz (mesmo que HasExited é verdadeiro e já temos um ExitCode). Notei que isso só acontece quando o arquivo em lotes contém comandos START e quando a saída padrão e / ou erro padrão são redirecionados. Por que WaitForExit () nunca retorna Qual é a maneira certa de esperar por esse processo para sair É seguro para apenas Poll Process. HasExited ou pode resultar em outros problemas PS. Eu só notei que chamar WaitForExit (100000) com um limite de tempo enorme (que definitivamente não expira) retorna imediatamente quando o processo sai. Estranho Sem tempo limite ele trava. Há uma diferença fundamental quando você chamar WaitForExit () sem um tempo limite, ele garante que o stdout / err redirecionados retornaram EOF. Isso garante que você leu toda a saída produzida pelo processo. Nós não podemos ver o que quotonOutputquot faz, mas altas chances de que deadlocks seu programa porque faz algo desagradável como assumindo que seu thread principal é ocioso quando ele é realmente preso em WaitForExit (). Ndash Hans Passant Nov 3 14 at 12:06 Este parece ser um artefato (id dizer bug) na implementação específica do manipulação assíncrona baseada em eventos de StandardOutput e StandardError. Percebi que enquanto eu era capaz de reproduzir facilmente o seu problema, simplesmente executando o código fornecido (excelente exemplo de código, por sinal.)), O processo não realmente pendurar indefinidamente. Em vez disso, ele retornou de WaitForExit () depois que ambos os processos filho que tinham sido iniciados tinham eles mesmos saído. Isso parece ser uma parte intencional da implementação da classe Process. Em particular, no método Process. WaitForExit (), uma vez que tenha terminado esperando no identificador de processo próprio, verifica para ver se um leitor para stdout ou stderr foi criado se assim, e se o valor de tempo limite para o WaitForExit ) É infinita (ie -1), o código realmente aguarda o fim-de-fluxo no leitor (s). Cada leitor respectivo é criado apenas quando o método BeginOutputReadLine () ou BeginErrorReadLine () é chamado. Os fluxos stdout e stderr não são fechados até que os processos filhos tenham fechado. Assim, esperar no final daqueles córregos irá bloquear até que isso aconteça. Que WaitForExit () deve se comportar de forma diferente dependendo se um chamou qualquer um dos métodos que iniciar a leitura baseada em eventos dos fluxos ou não, e especialmente dado que a leitura desses fluxos diretamente não faz com que WaitForExit () se comportam dessa maneira, cria Uma inconsistência na API que torna muito mais difícil de entender e usar. Embora Id pessoalmente chamar isso de um bug, eu suponho que é possível que o implementor (s) da classe Process estão cientes desta inconsistência e criado de propósito. Em qualquer caso, o work-around seria ler StandardOutput e StandardError diretamente em vez de usar a parte baseada em eventos da API. (Embora, claro, se os códigos fossem esperar nesses streams, ver-se-ia o mesmo comportamento de bloqueio até que os processos filhos fecham.) Por exemplo (C, porque eu não sei F bem o suficiente para bofetar um exemplo de código como este juntos rapidamente :)): Espero que o trabalho acima-around ou algo semelhante irá abordar a questão básica youve correr em. Meus agradecimentos ao comentarista Niels Vorgaard Christensen por me direcionar as linhas problemáticas no método WaitForExit (), para que eu pudesse melhorar essa resposta. Estou tentando executar um programa do PowerShell, aguarde a saída e, em seguida, obter acesso ao ExitCode, Mas não tendo muita sorte. Eu não quero usar - Wait com Start-Process, como eu preciso de algum processamento para continuar em segundo plano. Heres um script de teste simplificado: Executar este script fará com que o bloco de notas seja iniciado. Depois que este for fechado manualmente, o código de saída será impresso, e ele será iniciado novamente, sem usar - wait. Nenhum ExitCode é fornecido quando isso é sair: Eu preciso ser capaz de executar o processamento adicional entre iniciar o programa e à espera dele sair, então eu não posso fazer uso de - Wait. Qualquer idéia de como eu posso fazer isso e ainda ter acesso à propriedade. ExitCode a partir deste processo pediu 21 abr às 19:23 Há duas coisas para lembrar aqui. Um é adicionar o argumento - PassThru e dois é adicionar o argumento - Wait. Você precisa adicionar o argumento de espera por causa deste defeito connect. microsoft/PowerShell/feedback/details/520554/start-process-does-not-return-exitcode-property Depois de fazer esse objeto de um processo é passado para trás e você pode olhar Na propriedade ExitCode desse objeto. Aqui está um exemplo: Se você executá-lo sem - PassThru ou - Wait, ele vai imprimir nada. Eu sou workign em um programa que atua como um instalador para vários programas. Meu programa simples executa outros programas de instalação como processos de C. Eu estava tentando usar o evento process. Exited para desencadear o próximo passo da instalação, mas esse evento nunca parece ser disparado mesmo quando os processos está terminado e termina-se Alguém sabe por que isso é e uma solução para ele. Eu preciso de uma maneira de controlar as diferentes etapas de forma linear e evitar que vários processos sejam executados simultaneamente. Gostaria de usar o método. WaitForExit (), mas isso impede que o meu formulário do Windows de atualizar e colocar um objeto diferente em cima dele faz parecer que o formulário não está respondendo. Obrigado pela ajuda Segunda-feira, 20 de março de 2006 22:04 Respostas Tente definir a propriedade Process. EnableRaisingEvents como true. Tuesday, March 21, 2006 4:40 AM É porque os eventos estão sendo executados em outro segmento que você tem para empurrar as chamadas de volta para o thread principal usando control. invoke () weblogs. asp. net/justinrogers/articles/126345. Aspx inclui uma explicação detalhada. Terça-feira, 21 de março de 2006 19:27 Todas as respostas Tente definir a propriedade Process. EnableRaisingEvents como true. Terça-feira, 21 de março de 2006 4:40 AM Obrigado pela ponta Terça-feira, 21 de março de 2006 15:18 Essa linha de código que você me deu permite que os eventos sejam acionados, mas também causou alguns outros problemas Depois que o evento foi Eu não consigo alterar nenhuma das propriedades dos objetos do formulário. Ele diz que eles foram criados em outro segmento. Eu estou usando um P4 com hyperthreadign, mas eu não tenho sido doin programação thread. Eu tentei executar o programa com CheckForIllegalCrossThreadCalls falso o programa poderia executar, mas quando eu tentei abrir um novo formulário do evento funtion (ou de uma função chamada pela função de evento) o formulário não iria carregar corretamente e iria parar de responder Alguém tem uma idéias O que está causando isso e o que os processos têm a ver com ele. Terça-feira, 21 de março de 2006 4:09 PM Estou tendo o mesmo tipo de problema. Eu tenho um formulário com um botão e uma barra de progresso. Estou usando Process. Start () para dois (2) processos sob o evento buttonClick (). O que eu quero fazer é mostrar o status através de progrssbar após cada processo é concluído. Estou usando WaitForExit () para o processo para sair. Mas a barra prgress não é atualizada após cada chamada para Process. Start (). Parece que o formulário principal perde o foco quando um processo é iniciado e nunca recebe de volta até que todos os processos sejam concluídos. Eu tentei this. Active () no formulário após WaitForExit (), não funcionou. PrCA1.Exited novo EventHandler (ProcessExitedEvent), mas ele não trabalho. Qualquer pista sobre como atualizar a barra de progresso no formulário após cada chamada Processs. Start (). Aqui está o código de exemplo: com Progressbar1.Step 25 private void InstallClick (remetente do objeto, System. EventArgs e) // FPM Processo de Instalação prcA1 Process. Start (quotA1.exequot) //prcA1.Exited novo EventHandler (ProcessExitedEvent) // prcA1.EnableRaisingEvents true prcA1.WaitForExit () this. Activate () progressBar1.PerformStep () // Processo de Instalação do Driver prcB1 Process. Start (quotB1.exequot) // prcB1.Exited novo EventHandler (ProcessExitedEvent) // prcB1.EnableRaisingEvents true prcDriverB1. WaitForExit () progressBar1.PerformStep () // Processo de instalação do driver prcC1 Process. Start (quotC1.exequot) // prcC1.Exited novo EventHandler (ProcessExitedEvent) // prcC1.EnableRaisingEvents true prcC1.WaitForExit () progressBar1.PerformStep () // Processo de Instalação do Driver prcD1 Process. Start (quotD1.exequot) // prcD1.Exited novo EventHandler (ProcessExitedEvent) // prcD1.EnableRaisingEvents true prcD1.WaitForExit () progressBar1.PerformStep () // private void ProcessExitedEvent (object sender, System. EventArgs E) // // this. Activate () //progressBar1.PerformStep () // terça-feira, 21 de março de 2006 16:45

No comments:

Post a Comment