o log de Walter.
. Escrevendo enquanto aprende.
Sexta-feira, 18 de novembro de 2011.
Process. WaitForExit (Int32) trava o problema.
Como você pode ver, o código inicia um processo "cmd. exe" e passa para ele o comando que eu quero executar.
No código eu usei o comando ping - t 8.8.8.8 que, por causa da opção - t, pinga o host sem parar. O que acontece? O processo "cmd. exe" juntamente com o comando ping - t nunca sai e nunca fecha o fluxo stdout e, portanto, o código trava no Output = process. StandardOutput. ReadToEnd (); linha porque não pode ter sucesso lendo todo o fluxo.
O mesmo acontece também se um comando em um arquivo de lote for interrompido por algum motivo e, portanto, o código acima poderia funcionar continuamente por anos e, em seguida, travar repentinamente sem nenhum motivo aparente.
Você pode experimentar um deadlock se o comando que você anexar a "cmd. exe" ou o processo que você está chamando preencher a saída padrão ou o erro padrão. Isso porque nosso código não pode alcançar as linhas.
Na verdade, o processo filho (o comando ping ou um arquivo em lote ou qualquer outro processo que você esteja executando) não pode continuar se nosso programa não ler os buffers preenchidos dos fluxos e isso não pode acontecer porque o código está pendurado na linha com o processo. WaitForExit (), que irá esperar eternamente para o projeto filho sair.
O tamanho padrão de ambos os fluxos é de 4096 bytes. Você pode testar esses dois tamanhos com esses arquivos em lotes:
Process waitforexit timeout c #
No momento, estou trabalhando em um aplicativo Console Runner que possui o seguinte código para gerar o log e aguardar até que o processo seja concluído:
Eu tenho duas perguntas sobre esse pedaço de código.
Notei que se o processo demorar mais de 30 segundos, a chamada p. ExitCode explode. O que acontece se o meu processo demorar apenas 1 segundo, ele irá esperar 30 segundos de qualquer maneira ou o processo será avisado pelo CLR?
Se você tentar obter o ExitCode antes do processo ter sido encerrado, a tentativa lançará uma exceção. Examine a propriedade HasExited primeiro para verificar se o processo associado foi finalizado.
Não há garantia de que quando a sua chamada para WaitForExit retornar, o processo será encerrado. Da documentação do WaitForExit:
A sobrecarga WaitForExit (Int32) é usada para fazer o segmento atual aguardar até que o processo associado seja finalizado. Essa sobrecarga instrui o componente Process a aguardar uma quantidade finita de tempo para o processo sair. Se o processo associado não sair no final do intervalo porque a solicitação para finalizar é negada, false é retornado para o procedimento de chamada. Você pode especificar um número negativo (Infinito) por milissegundos e Process. WaitForExit (Int32) se comportará da mesma maneira que a sobrecarga WaitForExit (). Se você passar 0 (zero) para o método, ele retornará true somente se o processo já tiver saído; caso contrário, retorna imediatamente false.
Note que isso responde à sua segunda pergunta. Se o processo sair antes do tempo limite, WaitForExit retorna.
Desde que você especificou um tempo limite finito, você permite a possibilidade de a função retornar antes que o processo seja concluído. Então, você poderia escrever seu código assim:
Exemplo de uso.
Eu resolvi assim:
Eu redirecionei tanto a entrada, saída e erro e lidou com a leitura de fluxos de saída e erro. Essa solução funciona para o SDK 7- 8,1, tanto para o Windows 7 quanto para o Windows 8.
Eu tentei fazer uma classe que resolveria seu problema usando leitura de fluxo assíncrona, levando em consideração Mark Byers, Rob, stevejay respostas. Ao fazer isso, percebi que há um erro relacionado à leitura do fluxo de saída do processo assíncrono.
Você não pode fazer isso:
Você receberá System. InvalidOperationException: StandardOut não foi redirecionado ou o processo ainda não foi iniciado.
Então você precisa iniciar a leitura assíncrona 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 defini-los como assíncronos:
Então, algumas pessoas podem dizer que você só precisa ler o fluxo antes de defini-lo como assíncrono. Mas o mesmo problema ocorre. Haverá uma condição de corrida entre a leitura síncrona e o fluxo em modo assíncrono.
Não há como obter uma leitura assíncrona segura de um fluxo de saída de um processo na maneira real como "Process" e "ProcessStartInfo" foram projetados.
Provavelmente, é melhor usar a leitura assíncrona, como sugerido por outros usuários para o seu caso. Mas você deve estar ciente de que pode perder alguma informação 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 descartada (tentei as "soluções" das outras respostas).
Então decidi sugerir outra solução:
Este código depurado e funciona perfeitamente.
Introdução.
A resposta aceita atualmente não funciona (gera exceção) e há muitas soluções alternativas, mas nenhum código completo. Isto é, 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 o código completo com base em como eu quero usar o método Process. Start.
Eu usei-o para criar um diálogo de progresso em torno dos comandos do git. É assim que eu usei:
Em teoria, você também pode combinar stdout e stderr, mas eu não testei isso.
As outras soluções (incluindo EM0s) ainda estão em deadlock para meu aplicativo, devido a tempos limite internos e ao uso de StandardOutput e StandardError pelo aplicativo gerado. Aqui está o que funcionou para mim:
Editar: adicionada inicialização do StartInfo ao exemplo de código.
Este post talvez desatualizado, mas eu descobri a causa principal porque normalmente travar é devido ao estouro de pilha para a saída redirectStandard ou se você tiver redirectStandarderror.
Como os dados de saída ou os dados de erro são grandes, isso causará um tempo de interrupção, pois ainda está sendo processado por duração indefinida.
então, para resolver esse problema:
Eu acho que essa é uma abordagem simples e melhor (não precisamos do AutoResetEvent):
Eu estava tendo o mesmo problema, mas o motivo era diferente. No entanto, isso aconteceria no Windows 8, mas não no Windows 7. A linha a seguir parece ter causado o problema.
A solução foi NÃO desabilitar o UseShellExecute. Eu agora recebi uma janela popup do Shell, que é indesejada, mas muito melhor do que o programa esperando que nada de especial aconteça. Então eu adicionei a seguinte solução para isso:
Agora, a única coisa que me incomoda é por que isso está acontecendo no Windows 8 em primeiro lugar.
Eu sei que esta é a ceia de idade, mas, depois de ler esta página inteira, nenhuma das soluções estava funcionando para mim, embora eu não tenha tentado Muhammad Rehan como o código foi 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, eu acho que é algo a ver com o comprimento da saída antes de uma marca EOF.
De qualquer forma, a solução que funcionou para mim foi 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!
Depois de ler todos os posts aqui, resolvi a solução consolidada de Marko Avlijaš. No entanto, isso não resolveu todos os meus problemas.
Em nosso ambiente, temos um serviço do Windows que está programado para executar centenas de arquivos. bat. cmd. exe diferentes. etc arquivos que se acumularam ao longo dos anos e foram escritos por muitas pessoas diferentes e em diferentes estilos. Nós não temos controle sobre a escrita dos programas & amp; scripts, somos responsáveis apenas pelo agendamento, execução e geração de relatórios sobre 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 executada como um serviço, nem sempre captava stdout. Eu nunca cheguei ao fundo do por que não.
Process waitforexit timeout c #
Eu tenho o seguinte código no meu aplicativo:
System. Diagnostics. Process proc = new System. Diagnostics. Process ();
Uma vez que eu chamo isso através de outro aplicativo, o processo está pendente.
Então eu dei um tempo de 5 segundos e agora funciona bem. Mas preciso encontrar uma maneira melhor de corrigir esse problema, pois esse valor de tempo limite pode depender dos recursos do sistema e da quantidade de aplicativo de entrada que precisa ser processada.
Então, minha pergunta é se estamos criando um processo usando System. Diagnostics, o SO cria um thread separado e o torna como thread principal ou thread de interface do usuário?
Ou está criando um thread CLR que é o mesmo que System. Threading. Thread?
Se usarmos o pool de segmentos para criar um segmento de trabalho, essa seria uma opção melhor?
O pool de threads usa o agendamento do modo de usuário?
Aprecie sua ajuda nisso.
Eu preciso saber sobre isso, porque se System. Diagnostics também cria um segmento de plano de fundo ou segmento de trabalho, não adianta criar um thread separado novamente como não haverá nenhuma alteração no final do dia.
Qual é a diferença entre a implementação acima sobre a criação de um thread de segundo plano?
Você está confuso com tópicos internos e externos ao seu aplicativo. Se você usar WaitForExit no seu thread da interface do usuário. ele bloqueará o thread da interface do usuário, deixando-o sem resposta. Se isso for um problema, crie o novo processo no evento DoWork de um BackgroundWorker. Quando o processo termina, o RunWorkerCompleteEvent será acionado, alertando seu thread da interface do usuário.
Marcado como Resposta Min Zhu Microsoft contingent staff, Moderador segunda-feira, 18 de julho de 2011 3:10.
Todas as respostas.
Esperar por um evento com EnableRaisingEvents = false significa que você está usando o WaitForExit como temporizador. Defina para um valor apropriado.
Esperar por um evento com EnableRaisingEvents = false significa que você está usando o WaitForExit como temporizador. Defina para um valor apropriado.
Eu dei 5000 como o valor e resolvi o problema. Minha preocupação é que funcionará de maneira semelhante sob diferentes recursos do sistema, tamanho do conteúdo de entrada, etc.?
O que acontecerá se o processo associado não sair no final do intervalo?
O Windows não é um sistema operacional em tempo real, portanto, qualquer temporizador dependerá do agendamento do sistema operacional. Supostamente, o System. Timers. Timer é o mais preciso.
& quot; O que acontecerá se o processo associado não sair no final do intervalo? & quot; Você desativou este recurso. Se é isso que você está tentando fazer, habilite-o. Se você não quiser bloquear o encadeamento usado para iniciar o processo, inicie-o a partir de um encadeamento em segundo plano. O BackgxroundWorker seria apropriado para isso.
Eu preciso saber sobre isso, porque se System. Diagnostics também cria um segmento de plano de fundo ou segmento de trabalho, não adianta criar um thread separado novamente como não haverá nenhuma alteração no final do dia.
Qual é a diferença entre a implementação acima sobre a criação de um thread de segundo plano?
Eu preciso saber sobre isso, porque se System. Diagnostics também cria um segmento de plano de fundo ou segmento de trabalho, não adianta criar um thread separado novamente como não haverá nenhuma alteração no final do dia.
Qual é a diferença entre a implementação acima sobre a criação de um thread de segundo plano?
Você está confuso com tópicos internos e externos ao seu aplicativo. Se você usar WaitForExit no seu thread da interface do usuário. ele bloqueará o thread da interface do usuário, deixando-o sem resposta. Se isso for um problema, crie o novo processo no evento DoWork de um BackgroundWorker. Quando o processo termina, o RunWorkerCompleteEvent será acionado, alertando seu thread da interface do usuário.
Marcado como Resposta Min Zhu Microsoft contingent staff, Moderador segunda-feira, 18 de julho de 2011 3:10.
A Microsoft está realizando uma pesquisa online 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.
Process waitforexit timeout c #
Eu tenho uma ferramenta que pode demorar muito tempo para executar, mais do que o tempo limite padrão do Powershell para iniciar o processo de 600 segundos. Então, estou tentando encontrar uma maneira de aumentar esse tempo limite. Se meu código de teste for executado assim sem um tempo limite especificado:
Em seguida, o script aguarda corretamente que o comando seja executado e saia:
PS U: \ Meus documentos \ Desenvolvimento \ PowerShell & gt; \ ping_test. ps1.
No entanto, se eu tentar adicionar um tempo limite ao comando:
O processo de ping ainda é iniciado, mas imediatamente retorna ao script do PowerShell e eu recebo esta saída:
PS U: \ Meus documentos \ Desenvolvimento \ PowerShell & gt; \ ping_test. ps1.
Então, o que estou fazendo errado aqui?
O argumento para system. diagnostic. process. waitforexit () é em milissegundos.
Você disse para esperar por 1 segundo e depois sair.
Marcado como Resposta Tiger Li Microsoft employee terça-feira, 26 de julho de 2011 2:01.
A Microsoft está realizando uma pesquisa online para entender sua opinião sobre o site da Technet. Se você optar por participar, a pesquisa on-line será apresentada quando você sair do site da Technet.
Process waitforexit timeout c #
A sobrecarga WaitForExit () () () é usada para fazer o thread atual aguardar até que o processo associado termine. Este método instrui o componente Process a aguardar uma quantidade infinita de tempo para o processo sair. 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.
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.
Isto é claro para. O que faz você pensar que não espera que o processo do Note seja concluído? Quais são os sinais disso? Qual é a prova?
Processo p = new Process ();
MessageBox. Show (& quot; Agora o navegador deve estar fechado & quot;);
Exceto que você não consegue um objeto de processo que você possa usar. Se você tentar.
Dim myProc como novo processo ()
myProc = Process. Start (& quot; iexplore & quot ;, & quot; finance. yahoo/q/hp? s = & quot; símbolo +);
A Microsoft está realizando uma pesquisa online 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.
Eu tenho o seguinte código no meu aplicativo:
System. Diagnostics. Process proc = new System. Diagnostics. Process ();
Uma vez que eu chamo isso através de outro aplicativo, o processo está pendente.
Então eu dei um tempo de 5 segundos e agora funciona bem. Mas preciso encontrar uma maneira melhor de corrigir esse problema, pois esse valor de tempo limite pode depender dos recursos do sistema e da quantidade de aplicativo de entrada que precisa ser processada.
Então, minha pergunta é se estamos criando um processo usando System. Diagnostics, o SO cria um thread separado e o torna como thread principal ou thread de interface do usuário?
Ou está criando um thread CLR que é o mesmo que System. Threading. Thread?
Se usarmos o pool de segmentos para criar um segmento de trabalho, essa seria uma opção melhor?
O pool de threads usa o agendamento do modo de usuário?
Aprecie sua ajuda nisso.
Eu preciso saber sobre isso, porque se System. Diagnostics também cria um segmento de plano de fundo ou segmento de trabalho, não adianta criar um thread separado novamente como não haverá nenhuma alteração no final do dia.
Qual é a diferença entre a implementação acima sobre a criação de um thread de segundo plano?
Você está confuso com tópicos internos e externos ao seu aplicativo. Se você usar WaitForExit no seu thread da interface do usuário. ele bloqueará o thread da interface do usuário, deixando-o sem resposta. Se isso for um problema, crie o novo processo no evento DoWork de um BackgroundWorker. Quando o processo termina, o RunWorkerCompleteEvent será acionado, alertando seu thread da interface do usuário.
Marcado como Resposta Min Zhu Microsoft contingent staff, Moderador segunda-feira, 18 de julho de 2011 3:10.
Todas as respostas.
Esperar por um evento com EnableRaisingEvents = false significa que você está usando o WaitForExit como temporizador. Defina para um valor apropriado.
Esperar por um evento com EnableRaisingEvents = false significa que você está usando o WaitForExit como temporizador. Defina para um valor apropriado.
Eu dei 5000 como o valor e resolvi o problema. Minha preocupação é que funcionará de maneira semelhante sob diferentes recursos do sistema, tamanho do conteúdo de entrada, etc.?
O que acontecerá se o processo associado não sair no final do intervalo?
O Windows não é um sistema operacional em tempo real, portanto, qualquer temporizador dependerá do agendamento do sistema operacional. Supostamente, o System. Timers. Timer é o mais preciso.
& quot; O que acontecerá se o processo associado não sair no final do intervalo? & quot; Você desativou este recurso. Se é isso que você está tentando fazer, habilite-o. Se você não quiser bloquear o encadeamento usado para iniciar o processo, inicie-o a partir de um encadeamento em segundo plano. O BackgxroundWorker seria apropriado para isso.
Eu preciso saber sobre isso, porque se System. Diagnostics também cria um segmento de plano de fundo ou segmento de trabalho, não adianta criar um thread separado novamente como não haverá nenhuma alteração no final do dia.
Qual é a diferença entre a implementação acima sobre a criação de um thread de segundo plano?
Eu preciso saber sobre isso, porque se System. Diagnostics também cria um segmento de plano de fundo ou segmento de trabalho, não adianta criar um thread separado novamente como não haverá nenhuma alteração no final do dia.
Qual é a diferença entre a implementação acima sobre a criação de um thread de segundo plano?
Você está confuso com tópicos internos e externos ao seu aplicativo. Se você usar WaitForExit no seu thread da interface do usuário. ele bloqueará o thread da interface do usuário, deixando-o sem resposta. Se isso for um problema, crie o novo processo no evento DoWork de um BackgroundWorker. Quando o processo termina, o RunWorkerCompleteEvent será acionado, alertando seu thread da interface do usuário.
Marcado como Resposta Min Zhu Microsoft contingent staff, Moderador segunda-feira, 18 de julho de 2011 3:10.
A Microsoft está realizando uma pesquisa online 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.
Process waitforexit timeout c #
Eu tenho uma ferramenta que pode demorar muito tempo para executar, mais do que o tempo limite padrão do Powershell para iniciar o processo de 600 segundos. Então, estou tentando encontrar uma maneira de aumentar esse tempo limite. Se meu código de teste for executado assim sem um tempo limite especificado:
Em seguida, o script aguarda corretamente que o comando seja executado e saia:
PS U: \ Meus documentos \ Desenvolvimento \ PowerShell & gt; \ ping_test. ps1.
No entanto, se eu tentar adicionar um tempo limite ao comando:
O processo de ping ainda é iniciado, mas imediatamente retorna ao script do PowerShell e eu recebo esta saída:
PS U: \ Meus documentos \ Desenvolvimento \ PowerShell & gt; \ ping_test. ps1.
Então, o que estou fazendo errado aqui?
O argumento para system. diagnostic. process. waitforexit () é em milissegundos.
Você disse para esperar por 1 segundo e depois sair.
Marcado como Resposta Tiger Li Microsoft employee terça-feira, 26 de julho de 2011 2:01.
A Microsoft está realizando uma pesquisa online para entender sua opinião sobre o site da Technet. Se você optar por participar, a pesquisa on-line será apresentada quando você sair do site da Technet.
Process waitforexit timeout c #
A sobrecarga WaitForExit () () () é usada para fazer o thread atual aguardar até que o processo associado termine. Este método instrui o componente Process a aguardar uma quantidade infinita de tempo para o processo sair. 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.
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.
Isto é claro para. O que faz você pensar que não espera que o processo do Note seja concluído? Quais são os sinais disso? Qual é a prova?
Processo p = new Process ();
MessageBox. Show (& quot; Agora o navegador deve estar fechado & quot;);
Exceto que você não consegue um objeto de processo que você possa usar. Se você tentar.
Dim myProc como novo processo ()
myProc = Process. Start (& quot; iexplore & quot ;, & quot; finance. yahoo/q/hp? s = & quot; símbolo +);
A Microsoft está realizando uma pesquisa online 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.
A sobrecarga WaitForExit () () () é usada para fazer o thread atual aguardar até que o processo associado termine. Este método instrui o componente Process a aguardar uma quantidade infinita de tempo para o processo sair. 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.
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.
Isto é claro para. O que faz você pensar que não espera que o processo do Note seja concluído? Quais são os sinais disso? Qual é a prova?
Processo p = new Process ();
MessageBox. Show (& quot; Agora o navegador deve estar fechado & quot;);
Exceto que você não consegue um objeto de processo que você possa usar. Se você tentar.
Dim myProc como novo processo ()
myProc = Process. Start (& quot; iexplore & quot ;, & quot; finance. yahoo/q/hp? s = & quot; símbolo +);
A Microsoft está realizando uma pesquisa online 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.
No comments:
Post a Comment