Skip to main content

Waitforexit nunca retorna


Waitforexit nunca retorna
classe de processo. Essencialmente, estou usando process. start para lançar um exe e.
use o método waitforexit para aguardar a conclusão deste exe.
Por algum motivo desconhecido, o desempenho é piedoso. O mesmo exe quando.
O lançamento da caixa de execução é de cerca de 2 segundos. Ao usar process. start it.
fica por cerca de 22 segundos antes de completar aparentemente.
Como um trabalho, criei um componente com que executa a mesma tarefa e.
Neste caso de uso particular, o exe é concluído tão rápido quanto é executado.
Estou trabalhando em um projeto que usa os métodos start e waitforexit no.
classe de processo. Essencialmente, estou usando process. start para lançar um exe e.
use o método waitforexit para aguardar a conclusão deste exe.
Por algum motivo desconhecido, o desempenho é piedoso. O mesmo exe quando.
O lançamento da caixa de execução é de cerca de 2 segundos. Ao usar process. start it.
fica por cerca de 22 segundos antes de completar aparentemente.
Como um trabalho, criei um componente com que executa a mesma tarefa e.
Neste caso de uso particular, o exe é concluído tão rápido quanto é executado.
Não sabe o que diabos está fazendo aqui? Isso é um inseto?
retorna. Estou tentando executar um arquivo de morcego. WaitForExit nunca retorna.
Eu vejo (em taskmgr) que o exe que é chamado pelo arquivo de morcego é.
corrida. Se eu executar o morcego a partir da linha de comando, ele termina (sobre.
7 segundos). Se for um problema de permissões, não retornaria com um.

Waitforexit nunca retorna
Obter através da App Store Leia esta publicação em nosso aplicativo!
Process. WaitForExit doesn & # 39; t retornam mesmo que Process. HasExited seja verdade.
Eu uso Process. Start para iniciar um arquivo em lote. O arquivo em lote usa o comando "INICIAR" para iniciar vários programas em paralelo e depois sai.
Uma vez que o arquivo em lote é feito 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 faz (mesmo que HasExited é verdadeiro e já temos um ExitCode).
Percebi que isso só ocorre quando o arquivo em lotes contém comandos "INICIAR" e quando a saída padrão e / ou o erro padrão são redirecionados.
Por que WaitForExit () nunca retorna?
Qual é o caminho certo para esperar que esse processo saia?
É seguro apenas pesquisar Process. HasExited ou isso pode resultar em outros problemas?
PS .: Eu notei que chamar WaitForExit (100000) com um tempo limite enorme (que definitivamente não expira) retorna imediatamente quando o processo sai. Wierd. Sem tempo limite, trava.
Isso parece ser um artefato (eu diria "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 foi suspenso indefinidamente. Em vez disso, ele retornou de WaitForExit () uma vez que ambos os processos filho que tinham sido iniciados já haviam saído.
Esta parece ser uma parte intencional da implementação da classe Process. Em particular, no método Process. WaitForExit (), uma vez que acabou 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 a chamada WaitForExit () for "infinito" (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 faz WaitForExit () se comportar desse jeito, cria uma inconsistência na API que torna muito mais difícil de entender e usar. Enquanto eu pessoalmente chamaria isso de bug, suponho que seja possível que o (s) implementador (es) da classe Process esteja ciente dessa inconsistência e criou 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 de alguém aguardasse esses fluxos, verificaria o mesmo comportamento de bloqueio até que o filho fique próximo).
Por exemplo (C #, porque eu não sei F # bem o suficiente para tapar um exemplo de código como este juntos rapidamente :)):
Felizmente, o trabalho acima ou algo semelhante abordará o problema básico que você 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 essa resposta.

C # Hoje.
Deixe o # C # hoje!
Deixe o # C # hoje!
Como evitar deadlocks ao ler o console filho redirecionado no C # 2.
A leitura da saída da criança redirecionada parece ser uma tarefa fácil. Mas há desenvolvedores que lutam com o processo infantil pendurado por causa de bloqueios de leitura / leitura de console. E os deadlocks nunca são fáceis de investigar.
Consideremos um exemplo comum - um processo pai inicia um processo filho e lê toda a saída. Aqui está um exemplo de aplicação que pode simular o cenário.
O aplicativo pode ser executado em dois modos:
Processo principal - executa o processo filho e lê seu processo de saída infantil - imprime um pouco de saída.
Tudo funciona bem, mas consideremos um cenário em que o rendimento da criança é significativo maior.
Desta vez, o processo pai irá pendurar - é um impasse. Por quê? Vamos pensar o que o pai faz - primeiro ele configura o redirecionamento de saída do processo filho.
Em seguida, inicia o processo filho.
O passo consecutivo aguarda a conclusão do processo infantil.
E esse é o ponto onde o processo pai bloqueia com a criança. Por quê? O pai está aguardando que a criança termine e a criança tenha alguma dependência do pai também.
Primeiro, você precisa entender como o redirecionamento de saída funciona. Há um buffer criado para a saída. Quando a criança está escrevendo para o console, ele realmente está escrevendo para o buffer. Se a criança escreve muito, o buffer pode ficar cheio. Nesse caso, a criança trava no Console. Write até o buffer ter algum espaço.
O pai deve ler a saída da criança antes de esperar que a criança termine. Então, para corrigir o impasse, temos que trocar as seguintes linhas.
O código pai completo deve ser mostrado abaixo.
Observe que exatamente o mesmo problema pode acontecer com a saída de erro padrão (stderr). Além disso, um impasse semelhante pode acontecer com a escrita na entrada padrão da criança.
Basicamente você precisa ter muito cuidado e entender o que você está fazendo se quiser ler a entrada / saída da criança de forma síncrona.
Deixe um comentário Cancelar resposta.
2 pensamentos sobre & ldquo; Como evitar deadlocks ao ler o console filho redirecionado em C # & rdquo;
Venceu esse impasse ainda que o processo produza muito em stderr? Eu acho que é realmente seguro, você precisa usar os eventos em vez disso.
Correto, adicionei uma nota sobre o stderr.
Eu concordo que o manuseio assíncrono é uma maneira mais segura. I & # 8217; ll escrever uma postagem sobre isso também.

Первичная навигация.
Форум только для чтения.
Администраторы сделали этот форум доступным только для чтения. Новые беседы или комментарии не могут быть добавлены.
Processe hnags ao executar qualquer comando usando o & # 160; Process. Start ()
Porque se o Process. Start () for bem-sucedido, eu poderia começar a interrogar a saída.
O ManagementBaseObject retornado pelo InvokeMethod não contém o retorno de saída real pelo processo.
Eu acho que isso pode estar relacionado com o redirecionamento de saída / erro. Isso é feito de maneira sinônimo, então você não pode redirecionar os dois ao mesmo tempo. Para fazer isso, ele deve ser feito de forma assíncrona. (BeginOutputReadLine, BeginErrorReadLine)
& quot; O exemplo de código evita a condição de bloqueio executando operações de leitura assíncronas no fluxo StandardOutput. Um estado de impasse resulta se o processo pai chamar p. StandardOutput. ReadToEnd seguido de p. StandardError. ReadToEnd e o processo filho escreve texto suficiente para preencher o fluxo de erros. O processo pai aguardaria indefinidamente o processo filho para fechar o fluxo StandardOutput. O processo infantil esperaria indefinidamente para o pai ler o fluxo completo do StandardError.
Você pode usar operações de leitura assíncronas para evitar essas dependências e seu potencial de impasse. Alternativamente, você pode evitar a condição de bloqueio criando dois segmentos e lendo a saída de cada fluxo em um segmento separado. & Quot;
URL em VS2005 Documentação:
Você já descobriu esse problema? Estou inclinado a pensar que é um bug no material de personificação em 2.0. Se eu remover a representação, isso funciona bem. mesmo a re-direção da saída e erro. Mas no momento que você tenta executar o processo como outro usuário, o processo é iniciado, mas depois trava. Eu diria segurança, exceto que não existe um erro por si. O processo começa bem, mas depois trava. Se fosse segurança, pensaria que você nunca começaria o processo. Também é interessante porque o problema também entra em cascata através dos processos. Por exemplo, eu tentei envolver minha chamada de personificação em outro exe para que eu pudesse iniciar o programa inicial (do ASP) sem nenhuma representação. A mesma coisa acontece; o processo trava. não o processo de invólucro. O processo dentro do invólucro que está sendo representado trava! Louco. Se você executar o wrapper exe como qualquer usuário, ele também funciona bem, então eu sei que o wrapper funciona em todos os contextos que não sejam asp.
Alguém encontrou a solução para este problema?
Aqui está um que funciona no modo de depuração no ASP (2.xxx),
mas não funciona no modo publicado: ajuda!
classe pública myClass.
string público strBalance = string. Empty;
string privado runProc (string args)
Process proc = new Process ();
string passwordPre = & quot; MyPassword & quot ;;
char [] passwordChars = passwordPre. ToCharArray ();
SecureString password = new SecureString ();
foreach (char c in passwordChars)
return strBalance; // Eu nunca chego aqui publicado, eu trabalho em depuração.
strBalance & # 43; = e. Data; // Eu nunca chegar aqui em publicado, eu trabalho em depuração.
Беседа заблокирована.
Администраторы заблокировали эту беседу. Новые комментарии не могут быть добавлены.
© Майкрософт (Microsoft), 2018. Корпорация Microsoft сохраняет за собой все права, связанные с материалами на этом сайте.

George Birbilis @zoomicon.
Engenheiro de informática, Microsoft MVP J # & # 8211; R & amp; D 2004-2018, Borland Spirit of Delphi 2001.
Gotchas at Wait para um aplicativo descascado terminar (com / sem tempo limite) com.
Encontrei um exemplo útil do suporte da Microsoft chamado "Como aguardar a conclusão de um aplicativo descascado usando Visual Basic 2005 ou Visual Basic" em support. microsoft/kb/305368.
No entanto, note que existem várias gotchas com o código fornecido lá (apenas informou a Microsoft sobre isso, espero que eles tomem nota). Também o artigo aponta para as versões C # e C ++ da amostra que, obviamente, precisam das mesmas correções.
1) existe um problema tanto na primeira amostra (espere indefinidamente) como no segundo (espera com tempo limite)
& # 8216; Aguarde a janela de processo para concluir o carregamento.
& # 8216; Aguarde até que o processo saia.
Por que esperar pela entrada ocioso em primeiro lugar? O processo pode nunca entrar no estado ocioso e sair antes disso. De acordo com msdn. microsoft/en-us/library/8d7363e2(v=VS.90).aspx, você pode obter exceção de WaitForInputIdle:
Ocorreu um erro desconhecido. O processo não conseguiu entrar no estado ocioso.
O processo já foi encerrado.
Nenhum processo está associado a este objeto Processo.
Suponho que seja melhor evitar chamar WaitForInputIdle, pois você apenas se importa com WaitForExit lá.
2) Mesmo WaitForExit pode lançar exceções que o código deve verificar de acordo com msdn. microsoft/en-us/library/fb4aw7b8.aspx.
Não existe nenhum processo associado a este objeto Processo.
Você está tentando chamar WaitForExit para um processo que está sendo executado em um computador remoto. Este método está disponível somente para processos que estão sendo executados no computador local.
3) O artigo de suporte não menciona o documento WaitForExit (timeout) (msdn. microsoft/en-us/library/fb4aw7b8.aspx) sobre o tempo limite "infinito":
No Framework versão 3.5 e versões anteriores, a sobrecarga WaitForExit aguardava milissegundos MaxValue (aproximadamente 24 dias), não indefinidamente. Além disso, as versões anteriores não esperaram que os manipuladores de eventos saíssem se o tempo MaxValue completo fosse atingido.
Além disso, parece que a documentação para "WaitForExit (timeout)" não menciona que existe uma constante Timeout. Infinite que tem o valor -1 a usar para tais tempos limite infinitos (encontrado a partir do documento de Thread. Join): msdn. microsoft/ en-us / library / system. threading. timeout. infinite (v = VS.90).aspx.
4) A amostra não consegue chamar Close e, portanto, continua a gastar recursos para controlar o rastreamento (e "bloquear" aqueles identificadores de identificadores, obviamente, embora não seja tão fácil quanto em CPUs antigas e versões do sistema operacional ficar sem alças, espero).
Quando um processo associado sai (ou seja, quando é desligado pelo sistema de operação através de um término normal ou anormal), o sistema armazena informações administrativas sobre o processo e retorna ao componente que chamou WaitForExit. O componente Processo pode acessar a informação, que inclui o ExitTime, usando o Handle para o processo encerrado.
Como o processo associado saiu, a propriedade Handle do componente já não aponta para um recurso de processo existente. Em vez disso, o identificador pode ser usado apenas para acessar a informação do sistema operacional n. ° 8217 sobre o recurso do processo. O sistema está ciente de manipulações para processos que não foram lançados pelos componentes do Processo, portanto, mantém as informações ExitTime e Handle na memória até que o componente Processo liberte especificamente os recursos. Por esse motivo, sempre que você ligar para uma instância do Start for Process, chame Close quando o processo associado for encerrado e você não precisa mais de informações administrativas sobre isso. Fechar libera a memória alocada para o processo encerrado.
Observe também que poderia ter uma cláusula "Usando" ao definir o novo objeto de processo (em vez de Dim) em vez de obrigar explicitamente a "Processar fechar" no final para liberar recursos, conforme observado em msdn. microsoft/en - us / library / system. diagnostics. process. close (v = VS.90).aspx.
O método Fechar faz com que o processo pare de aguardar a saída se ele estivesse esperando, fecha o identificador do processo e limpa as propriedades específicas do processo. Fechar não fecha os leitores e escritores padrão de saída, entrada e erro caso estejam sendo referenciados externamente.
O método Dispose (Boolean) chama Close. Colocar o objeto Processo em um bloco de uso dispõe de recursos sem a necessidade de chamar Close.
5) Outro problema está na 2ª amostra (aguarde com tempo limite). Não menciona ter que chamar WaitForExit () novamente sem params após o WaitForExit (timeout) no caso em que a saída padrão foi redirecionada para manipuladores de eventos assíncronos (deve mencionar este caso para completude)
Quando a saída padrão foi redirecionada para manipuladores de eventos assíncronos, é possível que o processamento de saída não seja concluído quando esse método retornar. Para garantir que o tratamento de eventos assíncrono tenha sido concluído, chame a sobrecarga WaitForExit que não leva nenhum parâmetro depois de receber uma verdade dessa sobrecarga. Para ajudar a garantir que o evento Exited seja tratado corretamente nas aplicações Windows Forms, defina a propriedade SynchronizingObject.

Comments