Espalho de espera waitforexit


O código parece quase isso: como você pode ver, o código inicia um processo cmd. exe e passa para ele o comando que quero ser executado. Eu redireciono StandardError e StandarOutput para lê-los a partir do código. O código lê-los antes do processo. WaitForExit (Timeout) chamada conforme recomendado pela Microsoft (mais sobre isso mais tarde). O problema surge se o comando que eu envio para cmd. exe nunca termina ou trava indefinidamente. No código eu usei o comando ping - t 8.8.8.8 que, por causa da opção - t, pings o host sem parar. O que acontece O processo cmd. exe juntamente com o comando ping - t nunca sai e nunca fecha o fluxo de stdout e, portanto, o nosso código trava na linha Output. StandardOutput. ReadToEnd () do processo de saída porque não conseguiu ler todo o fluxo. O mesmo acontece também se um comando em um arquivo em lotes trava por qualquer motivo e, portanto, o código acima pode funcionar continuamente durante anos e, em seguida, é suspenso repentinamente sem nenhum motivo aparente. Antes de escrever, recomendava ler fluxos redirecionados antes do processo. WaitForExit (Timeout), bem, isso é especialmente verdadeiro se você usar a assinatura WaitForExit sem o tempo limite. Se você chamar processo. WaitForExit () antes de ler os fluxos redirecionados: código 2: você pode enfrentar um impasse se o comando que você anexar ao cmd. exe ou o processo que você está chamando preencher a saída padrão ou erro padrão. Isso porque nosso código não pode atingir as linhas de processo de saída. StandardOutput. ReadToEnd () De fato, o processo filho (o comando ping ou um arquivo em lote ou o processo que estiver executando) não pode continuar se o nosso programa não lê os buffers preenchidos dos fluxos e isso não pode acontecer porque o código está pendurado em A linha com o processo. WaitForExit () que aguardará para sempre que o projeto filho saia. O tamanho padrão de ambos os fluxos é de 4096 bytes. Você pode testar esses dois tamanhos com esses arquivos em lote: o primeiro script escreve 4096 bytes para a saída padrão e o segundo para erro padrão. Salve um destes em C: testbuffsize. bat e execute o processo de chamada do nosso programa. WaitForExit () antes do processo de saída. StandardOutput. ReadToEnd () como no código 2. Você pode fazê-lo escrevendo CommandResult Resultado ExecuteShellCommandSync (c: testbuffsize. bat, 1000) na linha 13 do código 1. O código não irá pendurar, mas se você escrever um byte mais em qualquer um dos dois fluxos, ele irá transbordar o tamanho do buffer tornando o programa aguentar. Se você precisa redirecionar e ler a saída padrão ou o erro padrão, a melhor solução é lê-los de forma assíncrona. Uma excelente maneira de fazer isso é proposta por Mark Byers neste segmento stackoverflow. Como a última coisa, observe que, se o processo filho sair apenas porque você usa o processo. WaitForExit (Timeout) assinatura e ele realmente vai no tempo limite, você deve matar o processo cmd. exe e seus possíveis filhos. WaitForExit () expira quando eu tento capturar multidões Stdout WaitForExit () expira quando eu tento capturar multi - Line Stdout Eu escrevi uma breve função VB (veja abaixo) que captura StandardOutput de um programa específico do Windows (myProgram. exe). O problema é este: se myProgram. exe retorna mais do que uma única linha de texto, então WaitForExit () sempre expira. A função funciona bem se myProgram. exe retornar apenas uma linha de texto. Também funciona bem com a saída de várias linhas - retornando uma String com novas linhas incorporadas - desde que eu remova o teste em WaitForExit (). Tenha em atenção que, se eu executar o myProgram. exe a partir da linha de comando, ele retorna rapidamente, não importa quantas linhas de texto eu tenha solicitado. A minha compreensão de WaitForExit () é que ele retorna True quando o processo que está esperando nas saídas ou False se o processo não foi encerrado após um número especificado de milissegundos. Claramente, eu devo ter entendido mal algo, mas não vejo nada na documentação on-line para sugerir por que isso importaria se a saída do programa contém uma linha ou muitos. Alguém pode me dizer o que estou fazendo errado Função pública myFunction (ByVal myOptions As String) Como String Dim psInfo como novo Diagnostics. ProcessStartInfo psInfo. FileName quotmyProgram. exequot psInfo. Arguments myOptions psInfo. CreateNoWindow True psInfo. UseShellExecute False psInfo. RedirectStandardOutput True Dim NewProc As Diagnostics. Process Diagnostics. Process. Start (psInfo) Dim myOutput como String quotquot Se newProc. WaitForExit (6000) Então myOutput newProc. StandardOutput. ReadToEnd newProc. StandardOutput. Close () newProc. Close () newProc. Dispose () Return MyOutput End Function - John Brock jbrockxxxxxx Re: WaitForExit () expira quando eu tento capturar multi-line Stdout On Mon, 07 Apr 2008 20:26:17 -0700, John Brock ltjbrockxxxxxxgt escreveu: gt. Gt Claramente, eu devo ter entendido mal alguma coisa, mas não vejo nada na documentação on-line para sugerir por que isso importaria se gt o resultado do programa contém uma linha ou muitos. Qualquer um pode me dizer o que estou fazendo errado Você redirecionou a saída padrão, mas você não está lendo isso quando você está bloqueado na chamada para WaitForExit (). Assim, quando o outro processo preenche o buffer de saída relativamente pequeno para saída padrão, ele bloqueia. Não pode continuar até ler dados da saída padrão, liberando o espaço do buffer para que ele possa emitir mais saída. Como você está usando ReadToEnd (), não há realmente nenhum motivo para você chamar WaitForExit (). Por definição, o fluxo de saída padrão não terminará até o processo ter encerrado. Então, você pode simplesmente chamar ReadToEnd (), e isso bloqueará até que o outro processo tenha saído, assim como WaitForExit () não teria redirecionado a saída. Os documentos, de fato, descrevem esse problema. Da página para ProcessStartInfo. RedirectStandardOutput: msdn2.microsoften-uslib. Ardoutput. aspx Quando o processo filho grava dados suficientes para preencher o fluxo redirecionado, ele depende do pai. O processo filho aguarda a próxima operação de gravação até que o pai lê do fluxo completo ou fecha o fluxo. A condição de deadlock resulta quando o chamador e o processo filho aguardam um para o outro para completar uma operação, e nenhuma delas pode continuar. O seu código não é bastante impassível, porque você incluiu um tempo limite que irá bloquear o impasse. Mas, de outra forma, esse é o cenário exato em que você está se deparando.

Comments

Popular posts from this blog

Forex piyasasi yorumlari

Microcogenerazione a gas naturale forex

Forex clock gadget