Monday, 7 May 2018

C # process waitforexit fechar


C # process waitforexit fechar
Então eu tenho lutado contra esse problema por algum tempo agora e tentei muitas maneiras diferentes de consertá-lo, mas não consegui.
Bascally que meu aplicativo faz é chama um arquivo java para carregar um aplicativo em um dispositivo. Enquanto ele está carregando é imprimi-lo para uma caixa richtext, então eu gostaria de passar para o próximo arquivo. O problema que estou tendo é que enquanto o primeiro arquivo está sendo carregado, o segundo tenta carregar quais problemas de casos. Eu tentei a espera pela saída, mas se eu fizer isso, os dados de saída não serão gravados na caixa rich text. Alguma ideia?
Eu tentei colocar a espera pela saída em muitos lugares diferentes, mas parece que não funciona.
Dois métodos abaixo escrevem o stdout ou erro para o campo richtext.
Qualquer ideia seria ótima. Bascally eu preciso do processo para sair, então eu posso continuar pensando o forloop para carregar o próximo arquivo.
Se você WaitForExit, seu aplicativo bloqueia (aguarda) até que o processo saia. Isso significa que não é possível processar nenhuma mensagem do Windows em seu thread da interface do usuário, portanto, ela não atualiza a interface do usuário.
Você precisa iniciar o processo "em segundo plano" para que sua interface do usuário continue sendo atualizada. Isso pode ser feito com:
Inicie e monitore o processo a partir de um thread separado e passe as informações de progresso de volta ao thread de interface do usuário para exibir Incluir um manipulador de eventos no evento de saída do processo ou periodicamente pesquisar o flag de process. HasExited e use isso para saber quando o primeiro processo acabado. Seu manipulador de eventos iniciaria esse processo e retornaria ao loop principal do aplicativo para que ele fosse executado normalmente enquanto aguardava a conclusão do processo externo.
Sente-se em um loop de espera ocupada até que seja concluído e processe os eventos do aplicativo. (Cuidado com isso, como qualquer evento que cause chamadas reentrantes para este código pode fazer coisas muito ruins. Geralmente, se você usar essa abordagem, você precisará certificar-se de que o restante de seu aplicativo está "bloqueado" em um estado em que ele saiba está ocupado esperando que um processo seja concluído). Isso é efetivamente o que o WaitForExit faz, mas também processa eventos de aplicativos, permitindo que a interface do usuário permaneça vagamente responsiva:

C # process waitforexit fechar
Eu tenho um aplicativo de console e um aplicativo de formulários ganhar que ambos precisam chamar para um servidor remoto para alguns dados, eles fazem uma chamada para a parte de linha de comando do Putty, plink. exe, para executar um comando remoto por SSH.
Eu criei uma pequena biblioteca de classes para compartilhar, executando o seguinte:
Sob o aplicativo de console tudo funciona bem, sob as formas de ganhar não erro, parece que WaitForExit () simplesmente não espera. Eu recebo uma string vazia para saída. Confirmei do servidor remoto que o usuário efetuou login, portanto, parece que o comando foi executado.

C # process waitforexit fechar
Você está executando console & quot; cmd & quot; ?
Se sim, então você tem que digitar exit também.
// Processo finalizado antes do período de tempo limite.
// Imprime mensagem de erro?
Eu gostaria de tentar isso, mas é muito de um hack. Eu tenho muitos comandos diferentes que levam diferentes quantidades de tempo (30 segundos a 25 minutos) para que não haja configuração em tempo real que eu possa colocar sem destruir meu desempenho. Esta função tem funcionado corretamente para vários comandos nos últimos 6 meses e agora ela decide me sacar. Eu tentei em um computador diferente sem problemas (o que realmente está mexendo comigo). Eu sei que não é o redirecionamento de saída / erro porque um novo WINDOW está sendo criado no servidor que eu estou remoting. Assim que fecho essa janela, meu processo sai como esperado e a saída correta é exibida no lado do usuário.
Obrigado por sua ajuda, mas estou ficando realmente frustrado com esse problema.
Sem conhecer os detalhes da mensagem, estamos apenas adivinhando o problema.
Você instalou o. NET 3.5 beta ou o Visual Studio 2008 beta?
Como você está usando o processo para iniciar o programa, Process. Start (& quot; file. exe & quot;), ou você está usando ProcessStartInfo?
Não, eu tenho o. NET 2003 e o. NET 2005 instalados.
proc = new Process ();
procSI = new ProcessStartInfo ();
Eu então configurei um novo thread para o StandardError e o StandardOutput.
Eu então escrevo meus comandos e.
if (redirecionando para fora do padrão)
Iniciar discussão para st. Fora.
Se (redirecionando erro padrão)
Iniciar discussão para st. erro.
Proc. WaitForExit (); & lt; -------- é onde ocorre a janela Relatório de erros do Windows genérico.
Traduzi o que pude da janela que aparece.
Veja também: Microsoft Visual Studio 2005, clique aqui para exibir o artigo traduzido
Porque o problema ocorre, ele termina o Microsoft Visual Studio 2005. Aplicamos a inconveniência, não há desculpa.
Obrigado novamente por todo o seu tempo.
Por que você está fazendo isso? Você não possui esse fluxo, então você não deveria estar fechando.
Isso é um erro de digitação? Antes de você estar falando sobre uma variável chamada "proc", não "Proc". Então, isso é simplesmente uma referência nula porque você está tentando invocar um método em uma referência diferente de & quot; proc & quot ;?
Você não deseja fechar o objeto sIn até que o aplicativo seja encerrado se você estiver redirecionando. Se o aplicativo gravar na saída padrão ou ler na entrada padrão depois de você fechar um deles, isso poderá causar uma exceção.
Você tem o rastreamento de pilha dessa mensagem de erro?
Você não deseja fechar o objeto sIn até que o aplicativo seja encerrado se você estiver redirecionando.
Não se deve fechar nenhum desses fluxos. O objeto Process possui-os e é o responsável pela limpeza após ele mesmo. Deve-se, na melhor das hipóteses, chamar Process. Dispose () depois de terminar com o objeto Process.
Eu criei o StreamWriter sIn antes de criar o objeto Process do processo. Eu então redireciono a entrada após o comando proc. Start (), então como eu não possuo isso? Independentemente disso, eu posso fazer a mudança para mover o sIn. Close () para depois da chamada WaitForExit para ver se isso faz alguma alteração.
O Proc foi um tipo, deveria ter sido proc.
Novamente, não é uma mensagem de erro, portanto, não há rastreamento de pilha. Meu redirecionamento StandardError está vazio e o redirecionamento de saída padrão contém o que eu esperava, mas nada indicando um erro. É por isso que tudo ainda funciona depois de fechar a janela Relatório de erros do Windows.
Vou postar o que acontece depois de mover a linha sIn. Close () abaixo da linha WaitForExit ().
Você não deseja fechar o objeto sIn até que o aplicativo seja encerrado se você estiver redirecionando.
Não se deve fechar nenhum desses fluxos. O objeto Process possui-os e é o responsável pela limpeza após ele mesmo. Deve-se, na melhor das hipóteses, chamar Process. Dispose () depois de terminar com o objeto Process.
Ok, eu estou fazendo Process. Close no bloco finally do meu código, por isso deve ser cuidado então.
Perdoem o meu comentário "não possuírem" o que fiz anteriormente. Acabei de voltar do almoço e estava perdendo o fato de que o processo tem controle sobre isso.
Process. Close é o método recomendado para fechar os fluxos padrão de entrada e saída padrão (e padrão).
Eu ficaria surpreso se o método Dispose não chamasse Close, pelo menos como parte de sua operação. Eu preferiria usar o fato de que, como o Process implementa IDisposable (indiretamente através do Componente de extensão que o implementa), deve-se chamar Dispose e deixar isso para a limpeza apropriada. Eu não recomendaria chamar Process. Close em vez de, nem além de Process. Dispose.
Process. Close é o método recomendado para fechar os fluxos padrão de entrada e saída padrão (e padrão).
Eu ficaria surpreso se o método Dispose não chamasse Close, pelo menos como parte de sua operação. Eu preferiria usar o fato de que, como o Process implementa IDisposable (indiretamente através do Componente de extensão que o implementa), deve-se chamar Dispose e deixar isso para a limpeza apropriada. Eu não recomendaria chamar Process. Close em vez de, nem além de Process. Dispose.
Como eu tenho certeza que você sabe, estes são funcionalmente equivalentes:
using (SomethingDisposable myObject =.)
// use myObject aqui.
// use myObject aqui.
if (myObject! = null) myObject. Dispose ();
Portanto, se a primeira recomendação é usar um bloco de uso, o melhor seria chamar Dispose, não Close, quando, como você disse, você sabe que está pronto com o objeto.
Por apenas chamar Close em algo que implementa IDisposable, o desenvolvedor está potencialmente cometendo um erro. Se Dispose fizer alguma limpeza adicional além de apenas delegar para Close, o programador está se preparando para um bug apenas chamando Close.
Pode haver um caso para chamar Close, mas somente se você não tiver terminado com o objeto, como você indicou na parte inferior da sua última resposta. Mas quando terminar, ligue para Dispose.
Como eu tenho certeza que você sabe, estes são funcionalmente equivalentes:
using (SomethingDisposable myObject =.)
// use myObject aqui.
// use myObject aqui.
if (myObject! = null) myObject. Dispose ();
Portanto, se a primeira recomendação é usar um bloco de uso, o melhor seria chamar Dispose, não Close, quando, como você disse, você sabe que está pronto com o objeto.
Por apenas chamar Close em algo que implementa IDisposable, o desenvolvedor está potencialmente cometendo um erro. Se Dispose fizer alguma limpeza adicional além de apenas delegar para Close, o programador está se preparando para um bug apenas chamando Close.
Pode haver um caso para chamar Close, mas somente se você não tiver terminado com o objeto, como você indicou na parte inferior da sua última resposta. Mas quando terminar, ligue para Dispose.
DisposableClass obj = new DisposableClass ();
ID descartável descartável = obj como IDisposable;
if (descartável! = nulo)
Mas sim, é isso que uma declaração de uso é "funcionalmente equivalente" para; mas eu não concordo explicitamente chamando Dispose na presença de um & quot; Close & quot; O método deve ser a primeira escolha devido à falta de escopo com a chamada Dispose. Por exemplo, o seguinte:
using (Process process = new Process ())
. é um erro de sintaxe.
Enquanto o seguinte:
Process process = new Process ();
// não há como garantir "processar & quot; não vai.
// ser acessado após o acima.
É um erro de tempo de execução (ObjectDisposedException). Usando Close não causa o erro de tempo de execução:
Process process = new Process ();
É sempre melhor trocar um erro em tempo de compilação por um erro em tempo de execução.
Então, eu configurei um ponto de interrupção após a chamada proc. WaitForExit () e ainda não atingi este ponto de interrupção. Então parece que isso é um grande problema.
Então, eu configurei um ponto de interrupção após a chamada proc. WaitForExit () e ainda não atingi este ponto de interrupção. Então parece que isso é um grande problema.
Eu tinha o serviço funcionando, mas eu parei porque ele tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim começando meu cliente. Eu descomentei a linha sIn. Close () agora mesmo e reiniciei o serviço e o Cliente e tudo está funcionando como antes. Eu posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de relatório de erros do Windows ainda (como era antes).
Então, no meu caso, eu preciso fechar o fluxo de entrada para poder sair do processo como esperado. Existem outras ideias?
Eu posso recomment a linha sIn. Close () se você quiser checar alguma coisa.
Eu tinha o serviço funcionando, mas eu parei porque ele tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim começando meu cliente. Eu descomentei a linha sIn. Close () agora mesmo e reiniciei o serviço e o Cliente e tudo está funcionando como antes. Eu posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de relatório de erros do Windows ainda (como era antes).
Então, no meu caso, eu preciso fechar o fluxo de entrada para poder sair do processo como esperado. Existem outras ideias?
Eu posso recomment a linha sIn. Close () se você quiser checar alguma coisa.
Como você está usando a entrada padrão e a saída padrão? Você está usando algum método ReadLine?
Peter, meu ponto é:
Se você não chamar Dispose em um objeto que implementa (direta ou indiretamente) IDisposable, então você está apenas pedindo um bug. Eu não quero discutir isso sem parar. Você pode continuar do jeito que você faz, e eu vou ficar com o meu. Contanto que não tenhamos que manter o código um do outro, tudo bem.
E, a propósito, um & quot; usando & quot; bloco não protege você também. Nada impede que você declare a variável fora do bloco (se bem me lembro), então ela ainda pode estar no escopo após o término do bloco. Você tem que ser diligente em escrever o código correto. Se você declarar no campo & quot; using & quot; declaração, isso é um caminho. Mas rejeitar usando a abordagem try / finally apenas porque deixa a variável no escopo não é realmente o ponto. Ainda precisa ser Dispose () em algum lugar.
Eu tinha o serviço funcionando, mas eu parei porque ele tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim começando meu cliente. Eu descomentei a linha sIn. Close () agora mesmo e reiniciei o serviço e o Cliente e tudo está funcionando como antes. Eu posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de relatório de erros do Windows ainda (como era antes).
Então, no meu caso, eu preciso fechar o fluxo de entrada para poder sair do processo como esperado. Existem outras ideias?
Eu posso recomment a linha sIn. Close () se você quiser checar alguma coisa.
Como você está usando a entrada padrão e a saída padrão? Você está usando algum método ReadLine?
Novamente, isso não é uma exceção que está sendo lançada, por isso não estou vendo detalhes de exceção. Eu não vou diretamente para o bloco catch no meu código, volto DIRETAMENTE após a chamada WaitForExit (). A janela que estou recebendo é a mesma que você recebe quando QUALQUER produto da Microsoft fecha inesperadamente e o MS quer informações sobre o Crash. Então, novamente, não há detalhes de exceção. No entanto, em um dos Logs do sistema, estou recebendo uma mensagem (traduzida do japonês)
& quot; Devenv. exe aplicação erros ocorrem, versão 8.0.50727.762 dos erros ocorridos módulo msvcr80.dll, versão 8.0.50727.762, erros ocorridos endereço 0x00039001.
Para obter mais informações, visite o site www. microsoft. com/fwlink/events. asp e consulte o Helo and Support Center. & Quot;
Estou redirecionando a entrada Padrão para passar os diferentes comandos porque estava tendo problemas para fazer com que funcionassem como eu queria formar o StartInfo. Estou redirecionando os fluxos de saída e erro para verificar o que eles contêm depois que o processo foi encerrado. Isso permitirá que eu verifique qualquer coisa que eu gostaria em qualquer fluxo, uma vez que tenhamos terminado. Também não permito que nenhum dos threads de redirecionamento de saída ou erro se junte até que o processo tenha passado pela chamada WaitForExit.
Estou completamente perplexo.
Peter, meu ponto é:
Se você não chamar Dispose em um objeto que implementa (direta ou indiretamente) IDisposable, então você está apenas pedindo um bug. Eu não quero discutir isso sem parar. Você pode continuar do jeito que você faz, e eu vou ficar com o meu. Contanto que não tenhamos que manter o código um do outro, tudo bem.
Eu não concordo. Não é um "bug" para não chamar Dispose. Seus recursos não serão liberados imediatamente, mas o GC os liberará se precisar da memória (supondo que o padrão Dispose esteja adequadamente implementado e exista um finalizador). Se a turma que você está usando implementa um & quot; Fechar & quot; método que não faz as mesmas coisas que "Dispose", Close deve ser documentado como tal ou há um bug na classe. Eu nunca encontrei uma classe de framework que implementa IDisposable e um método Close () que introduziu um & quot; leak & quot; quando Close foi chamado sem chamar Dispose. O padrão esmagador para Dispose / Close é que Dispose calls Close, bem como a configuração de um & quot; disposed & quot; flag (usado para jogar ObjectDisposedException).
Na verdade, isso é detalhado na Referência Geral do. NET Framework: “Ocasionalmente, um nome específico de domínio é mais apropriado que Dispose. Por exemplo, um encapsulamento de arquivo pode querer usar o nome do método Close. Nesse caso, implemente Dispose de forma particular e crie um método Close público que chame Dispose. O exemplo de código a seguir ilustra esse padrão. Você pode substituir Fechar por um nome de método apropriado ao seu domínio. & Quot; de Implementar Finalizar e Descartar para Limpar Recursos Não Gerenciados.
Assim como & quot; Para certas classes de objetos, como arquivos ou objetos de conexão com o banco de dados, um método Close representa melhor a operação lógica que deve ser executada quando o consumidor do objeto tiver terminado o objeto. & Quot; de Melhorando o Desempenho do Código Gerenciado (embora também detalhe "Em casos bem escritos, ambos são funcionalmente equivalentes". Isso implica que o uso de Close é mais claro com "representa melhor").
E, a propósito, um & quot; usando & quot; bloco não protege você também. Nada impede que você declare a variável fora do bloco (se bem me lembro), então ela ainda pode estar no escopo após o término do bloco. Você tem que ser diligente em escrever o código correto. Se você declarar no campo & quot; using & quot; declaração, isso é um caminho. Mas rejeitar usando a abordagem try / finally apenas porque deixa a variável no escopo não é realmente o ponto. Ainda precisa ser Dispose () em algum lugar.

Processo . Método WaitForExit ()
A documentação de referência da API. NET tem uma nova página. Visite o Navegador da API. NET em docs. microsoft para ver a nova experiência.
Instrui o componente Processo a aguardar indefinidamente que o processo associado seja encerrado.
Assembly: System (no System. dll)
A configuração de espera não pôde ser acessada.
Nenhuma identificação de processo foi definida e uma Handle da qual a propriedade Id pode ser determinada não existe.
Não há processo associado a este objeto Process.
Você está tentando chamar WaitForExit () para um processo que está sendo executado em um computador remoto. Este método está disponível apenas para processos em execução no computador local.
WaitForExit () faz com que o segmento atual espere até que o processo associado termine. Deve ser chamado depois que todos os outros métodos forem chamados no processo. Para evitar o bloqueio do segmento atual, use o evento Exited.
Este método instrui o componente Process a aguardar uma quantidade infinita de tempo para que os manipuladores de processo e evento saiam. Isso pode fazer com que um aplicativo pare de responder. Por exemplo, se você chamar CloseMainWindow para um processo que tenha uma interface com o usuário, a solicitação para o sistema operacional finalizar o processo associado poderá não ser tratada se o processo for gravado para nunca inserir seu loop de mensagem.
No. NET Framework 3.5 e versões anteriores, a sobrecarga WaitForExit () aguardou milissegundos MaxValue (aproximadamente 24 dias), não indefinidamente. Além disso, as versões anteriores não esperavam que os manipuladores de eventos saíssem se o tempo máximo de MaxValue fosse atingido.
Essa sobrecarga assegura que todo o processamento tenha sido 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 tiver sido redirecionada para manipuladores de eventos assíncronos.
Quando um processo associado é encerrado (ou seja, quando é encerrado pelo sistema operacional por meio de uma finalização normal ou anormal), o sistema armazena informações administrativas sobre o processo e retorna ao componente que chamou WaitForExit (). O componente de processo pode acessar as informações, que inclui o ExitTime, usando o identificador para o processo de saída.
Como o processo associado foi encerrado, a propriedade Handle do componente não aponta mais 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 identificadores para processos que não foram liberados pelos componentes do processo, portanto, ele mantém as informações de ExitTime e identificador na memória até que o componente de processo especificamente libera os recursos. Por esse motivo, sempre que você chamar a instância Start for Process, chame Close quando o processo associado tiver terminado e você não precisar mais de nenhuma informação administrativa sobre ele. Close libera a memória alocada para o processo finalizado.

C # process waitforexit fechar
Então eu tenho lutado contra esse problema por algum tempo agora e tentei muitas maneiras diferentes de consertá-lo, mas não consegui.
Bascally que meu aplicativo faz é chama um arquivo java para carregar um aplicativo em um dispositivo. Enquanto ele está carregando é imprimi-lo para uma caixa richtext, então eu gostaria de passar para o próximo arquivo. O problema que estou tendo é que enquanto o primeiro arquivo está sendo carregado, o segundo tenta carregar quais problemas de casos. Eu tentei a espera pela saída, mas se eu fizer isso, os dados de saída não serão gravados na caixa rich text. Alguma ideia?
Eu tentei colocar a espera pela saída em muitos lugares diferentes, mas parece que não funciona.
Dois métodos abaixo escrevem o stdout ou erro para o campo richtext.
Qualquer ideia seria ótima. Bascally eu preciso do processo para sair, então eu posso continuar pensando o forloop para carregar o próximo arquivo.
Se você WaitForExit, seu aplicativo bloqueia (aguarda) até que o processo saia. Isso significa que não é possível processar nenhuma mensagem do Windows em seu thread da interface do usuário, portanto, ela não atualiza a interface do usuário.
Você precisa iniciar o processo "em segundo plano" para que sua interface do usuário continue sendo atualizada. Isso pode ser feito com:
Inicie e monitore o processo a partir de um thread separado e passe as informações de progresso de volta ao thread de interface do usuário para exibir Incluir um manipulador de eventos no evento de saída do processo ou periodicamente pesquisar o flag de process. HasExited e use isso para saber quando o primeiro processo acabado. Seu manipulador de eventos iniciaria esse processo e retornaria ao loop principal do aplicativo para que ele fosse executado normalmente enquanto aguardava a conclusão do processo externo.
Sente-se em um loop de espera ocupada até que seja concluído e processe os eventos do aplicativo. (Cuidado com isso, como qualquer evento que cause chamadas reentrantes para este código pode fazer coisas muito ruins. Geralmente, se você usar essa abordagem, você precisará certificar-se de que o restante de seu aplicativo está "bloqueado" em um estado em que ele saiba está ocupado esperando que um processo seja concluído). Isso é efetivamente o que o WaitForExit faz, mas também processa eventos de aplicativos, permitindo que a interface do usuário permaneça vagamente responsiva:

No comments:

Post a Comment