Wednesday, 4 April 2018

Processo espera antes de fechar


Processo waitforexit fechar
Por favor, você pode ajudar com um problema de Processo que estou enfrentando e espero que responda algumas perguntas sobre o método que estou usando.
Eu tenho um aplicativo que chama outro, aguarda a conclusão e, em seguida, continua com o seu trabalho. Isso, em geral, funciona bem, mas às vezes ele congela o dispositivo (exigindo uma reinicialização suave) ou o dispositivo reabastece de qualquer maneira.
O pseudo-código é:
Dim ExitLoop como booleano.
Dim p como novo processo.
Faça algo bastante vivo correndo.
1) O waitforexit retorna logo após o Application. Exit no Application2 ou ele retorna depois que a bomba da mensagem terminar.
2) Feche a espera até que a bomba da mensagem termine. Ou fechará o retorno imediatamente e p. dispose tente dispor o processo enquanto ele ainda está fechando.
3) Não devo incomodar com waitforexit e tentar algo como o seguinte:
4) Por que um dispositivo do Windows Mobile 6 realizaria uma reinicialização suave. Poderia ficar sem memória ...
Dim ExitLoop como booleano.
Se p. HasExited Then ExitLoop = True.
Loop While Not ExitLoop.
Tentei várias implementações, mas ainda não consegui 100% de sucesso.
Obrigado pelo seu tempo.
Após novos testes, encontrei o seguinte:
Relatórios MSDN que eu não deveria estar usando process. dispose, presumivelmente isso é chamado após process. close terminou e está em seu próprio segmento.
Apesar do fato de que existe um processo. Na verdade, todos os exemplos da Microsoft não o usam, favorecendo o método abaixo.
thread. sleep (por um pouco)
loop enquanto não process. hasexited.
continue com sua aplicação.
Eu decidi usar o CERunAppAtTime como este todo o sistema. O exercício de diagnóstico me custou mais tempo de desenvolvimento do que deveria ter feito.
Seria útil para outros e o desenvolvimento do Compact Framework se o comportamento que experimentei pode ser explicado.
A Microsoft está conduzindo 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ê sair do site do Msdn.

Processo waitforexit fechar
Obter através da App Store Leia esta publicação em nosso aplicativo!
O process. kill () finaliza o WaitForExit () (sem limite de tempo)
Eu tenho um processo que é executado em segundo plano e tem WaitForExit (), uma vez que a duração pode variar e preciso aguardar até que ele termine. Em ocasiões, eu preciso terminar antes de completar e desencadeio o comando. Kill () através de um evento de classe. A propriedade. HasExited muda para true, mas o código nunca passa a linha WaitForExit ().
Meu processo lança um cliente de transferência de arquivos baseado em java e executa uma transferência. O processo aparece no gerenciador de tarefas e Kill () não termina. Como eu realmente não me importo em terminar o processo, mas preciso que meu programa vá para a próxima "tarefa", adicionei Close () logo após Kill (), que libera o WaitForExit e deixa meu código "seguir em frente". Terminar o processo cedo será uma ocorrência rara no meu aplicativo, mas ainda preciso que ele funcione, então essa implementação terá que fazer.
WaitForExit é uma chamada direta ao sistema operacional para aguardar que o identificador de processo seja sinalizado. Quando um processo termina, o WaitForExit será concluído. Kill é uma chamada direta para TerminateProcess, que é uma matança sem perguntas. Se usado corretamente WaitForExit retornará depois que Kill for concluída.
Então, há algum outro erro em seu código. Crie uma reprodução mais simples e você verá o problema desaparecer. O bug está escondido na complexidade do seu código.
Ou, WaitForExit retornou, mas você não percebeu. Ou, Kill nunca foi executado ou falhou. Mais uma vez, a simplificação do código revelará o problema. Você pode trazer para uma reprografia de 5 linhas? Eu duvido que você possa, mas vou olhar novamente se você fizer isso.
Nos comentários, você especificou que o kill ping funciona, mas matar seu processo especial não. A causa disso geralmente não é cancelável IO. O kernel do Windows mantém processos ao redor até que todos os IO sejam feitos. A boa notícia é que o processo irá morrer eventualmente e nenhum código será executado depois que Kill tenha retornado. A má notícia é que a limpeza de recursos não está totalmente concluída.

Exemplo de uso.
Resolvi assim:
Eu redirecionava a entrada, a saída e o erro e administrai a leitura dos fluxos de saída e erro. Esta solução funciona para o SDK 7- 8.1, tanto para o Windows 7 como para o Windows 8.
Eu tentei fazer uma aula que resolva seu problema usando a leitura de fluxo assíncrono, levando em conta Mark Byers, Rob, Stevejay responde. Ao fazê-lo, percebi que existe um erro relacionado à leitura assíncrona do fluxo de saída do processo.
Você não pode fazer isso:
Você receberá System. InvalidOperationException: StandardOut não foi redirecionado ou o processo ainda não começou.
Então, você deve iniciar a saída assíncrona lida após o processo ser iniciado:
Fazendo isso, faça uma condição de corrida porque o fluxo de saída pode receber dados antes de configurá-lo como assíncrono:
Então algumas pessoas podem dizer que você só precisa ler o fluxo antes de configurá-lo como assíncrono. Mas o mesmo problema ocorre. Haverá uma condição de corrida entre a leitura síncrona e configurará o fluxo em modo assíncrono.
Não há como conseguir uma leitura assíncrona segura de um fluxo de saída de um processo na forma real "Processo" e "ProcessStartInfo" foi projetado.
Você provavelmente está melhor usando a leitura assíncrona, como sugerido por outros usuários para o seu caso. Mas você deve estar ciente de que você pode perder algumas informações devido à condição de corrida.
Nenhuma das respostas acima está fazendo o trabalho.
A solução Rob trava e a solução 'Mark Byers' obtém a exceção descarta. (Eu tentei as "soluções" das outras respostas).
Então eu decidi sugerir outra solução:
Este código é depurado e funciona perfeitamente.
Introdução.
A resposta atualmente aceita não funciona (lança exceção) e há muitas soluções alternativas, mas nenhum código completo. Isso é, obviamente, desperdiçando muito tempo das pessoas porque esta é uma questão popular.
Combinando a resposta de Mark Byers e a resposta de Karol Tyl, escrevi um código completo baseado em como eu quero usar o método Process. Start.
Eu usei-o para criar um diálogo de progresso em torno dos comandos git. É assim que eu usei isso:
Em teoria, você também pode combinar stdout e stderr, mas não testei isso.
Este post talvez esteja desactualizado, mas descobri a principal causa por que normalmente ele trava é devido ao excesso de pilha para o redirectStandardoutput ou se você tem redirectStandarderror.
Como os dados de saída ou os dados de erro são grandes, isso causará um tempo de espera, pois ele ainda está processando por tempo indefinido.
para resolver esse problema:
Eu acho que isso é uma abordagem simples e melhor (não precisamos do AutoResetEvent):
Eu estava tendo o mesmo problema, mas a razão era diferente. No entanto, isso aconteceria no Windows 8, mas não no Windows 7. A seguinte linha parece ter causado o problema.
A solução era NÃO desativar UseShellExecute. Agora recebi uma janela popup do Shell, que é indesejável, mas muito melhor do que o programa esperando que nada de particular aconteça. Então eu adicionei o seguinte trabalho para isso:
Agora, o único problema que me incomoda é o porquê isso está acontecendo no Windows 8, em primeiro lugar.
Eu sei que isso é velho, mas, depois de ler toda essa página, nenhuma das soluções estava funcionando para mim, embora eu não tentei Muhammad Rehan porque o código era um pouco difícil de seguir, embora eu acho que ele estava no caminho certo . Quando eu digo que não funcionou, isso não é inteiramente verdade, às vezes funcionaria bem, acho que é algo a ver com a duração da saída antes de uma marca EOF.
De qualquer forma, a solução que funcionou para mim era usar diferentes threads para ler o StandardOutput e StandardError e escrever as mensagens.
Espero que isso ajude alguém, que pensou que isso poderia ser tão difícil!
As outras soluções (incluindo o EM0) ainda estão bloqueadas para o meu aplicativo, devido a tempos de espera internos e ao uso de StandardOutput e StandardError pela aplicação gerada. Aqui está o que funcionou para mim:
Editar: inicialização adicionada de StartInfo para codificar a amostra.
Depois de ler todos os posts aqui, resolvi a solução consolidada de Marko Avlijaš. No entanto, não resolveu todos os meus problemas.
Em nosso ambiente, temos um Serviço do Windows que está programado para executar centenas de diferentes. bat. cmd. exe. etc arquivos que se acumularam ao longo dos anos e foram escritas por muitas pessoas diferentes e em diferentes estilos. Não temos controle sobre a redação dos programas e programas; scripts, somos apenas responsáveis ​​pelo agendamento, execução e relatórios sobre o sucesso / falha.
Então eu tentei praticamente todas as sugestões aqui com diferentes níveis de sucesso. A resposta de Marko foi quase perfeita, mas quando executado como um serviço, ele nem sempre captou stdout. Nunca cheguei ao fundo do porquê não.

Processo waitforexit fechar
Obter através da App Store Leia esta publicação em nosso aplicativo!
Se eu matar um System. Diagnostics. Process com. Kill (), também preciso chamar. Fechar ()?
Usando C # 4.0, eu criei um System. Diagnostics. Process que eu espero levar um curto período de tempo para ser executado. Se, por algum motivo, o processo não tiver saído após algum tempo (por exemplo, eu chamei. WaitForExit (tempo limite) e o valor de retorno era falso), preciso limpar. Eu decidi que é seguro usar. Kill () nesta situação particular (não há estruturas de dados que estou preocupada com corrupção).
Dada esta configuração, eu também preciso chamar o método. Fechar () do Processo? Em caso afirmativo, devo chamar. Fechar () antes ou depois. Kill ()?
O System. Diagnostics. Process implementa IDisposable por meio da classe Component, e o método Dispose (bool) protegido chama Close (). Em geral, é considerado boa prática descartar recursos descartáveis ​​quando você terminar com eles, pois isso liberará imediatamente quaisquer recursos associados à classe (não ter que esperar pela execução do GC).
Então, para responder sua pergunta:
Sim, ligue para Close () ao chamar o método Dispose () diretamente ou através da construção usando C # da seguinte maneira.
Process. Kill () e Process. Close () internamente chamam Close () no objeto SafeProcessHandle particular associado ao processo. No entanto, Process. Close () também redefine explicitamente vários outros membros internos.
Uma vez que o Processo implementa IDisposable, você sempre deve chamar Close () nela quando terminar, ou colocá-la em um bloco usando.

Processo waitforexit fechar
Dentro de um aplicativo que estou escrevendo, preciso fazer o seguinte:
Execute um aplicativo GUI externo (para os propósitos deste exemplo, vamos assumir o seu MS Word). Bloqueie o segmento atual até que o aplicativo GUI externo tenha sido fechado.
Minha primeira tentativa de fazer isso foi fazer uso do objeto System. Diagnostics. Process.
// Inicialize o objeto de processo.
myProcess. StartInfo. FileName = & quot; C: \\ Arquivos de Programas \\ Microsoft Office \\ OFFICE11 \\ Winword. exe & quot ;;
myProcess. StartInfo. WorkingDirectory = & quot; C: \\ Arquivos de Programas \\ Microsoft Office \\ OFFICE11 & quot ;;
// Inicie o processo e aguarde que ele seja fechado.
System. Windows. Forms. MessageBox. Show (& quot; Aplicativo de usuário fechado & quot;);
Quando eu executo o código acima, o MS Word é iniciado como esperado. No entanto, a chamada WaitForExit () não parece estar fazendo seu trabalho como eu obter o instantâneo de caixa de mensagem instantaneamente após o processo do MS Word é iniciado e não depois que ele for fechado.
Por que a chamada WaitForExit () não aguarda o término do processo do MSWord? O fato de eu estar lançando um aplicativo GUI em vez de um aplicativo de linha de comando é significativo?
Qualquer ajuda seria muito apreciada.
Todas as respostas.
Depois de alguns testes, concluí que é porque não há um documento de usuário carregado. Se você fizer o parâmetro do nome do arquivo um documento real funciona como esperado:
// Inicie o processo e aguarde que ele seja fechado.
System. Windows. Forms. MessageBox. Show (& quot; Aplicativo de usuário fechado & quot;);
Seja ou não um documento carregado, não deve ser importante? O objeto Processo apenas fornece uma maneira genérica de executar e monitorar processos, não sabe nada sobre os internos do que o Word carregou com segurança?
Em qualquer caso, tentei o código conforme recomendado e recebi uma exceção "Nenhum processo associado a este objeto", presumivelmente porque foi passado o nome do arquivo de um documento em vez de um executável.
(Eu também devo mencionar que estou usando apenas o Word como um exemplo aqui para resolver esse problema em particular, e por isso não quero ficar muito preso ao que está acontecendo na própria Word. Eu tentei e falhei em usar o WaitForExit. () com uma variedade de aplicativos GUI.)
OK, acabei de chegar em casa e tentei isso no meu PC doméstico, e você não saberia que o código funciona! Não tenho certeza por que causa problemas no laptop do meu trabalho.
Em qualquer caso, obrigado por você ajudar a DMan.
Proposta como resposta por Brad Mathews sexta-feira, 19 de dezembro de 2008 12:55.
objProcess As New System. Diagnostics. ProcessStartInfo (& quot; Winword. exe & quot; / t c: \ mydoc. doc & quot;)
A Microsoft está conduzindo 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ê sair do site do Msdn.

Processo . Método WaitForExit ()
A documentação de referência da API tem uma nova casa. Visite o navegador da API no docs. microsoft para ver a nova experiência.
Instrui o componente Processo a esperar indefinidamente para que o processo associado saia.
Assembly: System (no System. dll)
A configuração de espera não pôde ser acessada.
Nenhum Id do processo foi configurado e um identificador do qual a propriedade Id pode ser determinada não existe.
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.
WaitForExit () faz o thread atual aguardar até o processo associado terminar. Ele deve ser chamado após todos os outros métodos serem chamados no processo. Para evitar o bloqueio do segmento atual, use o evento Exitado.
Esse método instrui o componente Processo a aguardar uma quantidade infinita de tempo para que o processo e os manipuladores de eventos saem. Isso pode fazer com que um aplicativo pare de responder. Por exemplo, se você chamar CloseMainWindow para um processo que tenha uma interface de usuário, a solicitação ao sistema operacional para encerrar o processo associado pode não ser tratada se o processo for gravado para nunca entrar no loop de mensagem.
No Quadro 3.5 e versões anteriores, a sobrecarga WaitForExit () esperava 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.
Esta sobrecarga garante que todo o processamento foi concluído, incluindo o tratamento de eventos assíncronos para saída padrão redirecionada. Você deve usar essa sobrecarga após uma chamada para a sobrecarga WaitForExit (Int32) quando a saída padrão foi redirecionada para manipuladores de eventos assíncronos.
Quando um processo associado sai (ou seja, quando é encerrado 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 as informações do sistema operacional 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. Close libera a memória alocada para o processo finalizado.
Consulte a seção Comentários da página de referência da propriedade StandardError.
para confiança total para o chamador imediato. Este membro não pode ser usado por código parcialmente confiável.

No comments:

Post a Comment