C # Process Waitforexit Readtoend
Eu tenho um programa que freqüentemente usa um programa externo e lê suas saídas. Isso funciona muito bem, usando seu processo usual de redirecionamento de saída, mas um argumento específico, por algum motivo, trava quando eu tento lê-lo, nenhuma mensagem de erro - nenhuma exceção, ele simplesmente pára quando ele atinge essa linha. Naturalmente, eu uso uma função centralizada para chamar e ler a saída do programa, que é esta: a linha que trava é resultado proc. StandardOutput. ReadToEnd (). Mas novamente, não todas as vezes, somente quando enviado um argumento específico (servidor inicial). Todos os outros argumentos funcionam bem - lê o valor e o retorna. Também é estranho do jeito que ele trava. Ele não congela ou comete um erro ou qualquer coisa, ele simplesmente pára de processar. Como se fosse um comando de retorno, exceto que ele nem sequer retornava à função de chamada, ele simplesmente pára tudo com a interface ainda está funcionando. Qualquer um experimentou isso antes Alguém tem alguma ideia do que eu deveria tentar Im assumindo que é algo inesperado dentro do fluxo em si, mas existe uma maneira de lidar com isso para que ele lira de qualquer maneira, perguntou o 23 de agosto 11 às 11:19 Executar no console o mesmo Programa com os mesmos parâmetros. Ele está solicitando a interação do usuário, como inserir senha ou congestão após advertências, pode ser a causa. Por exemplo, pgAdmin (administração de banco de dados de pós-publicação) trava solicitando senha para bancos de dados que não estão em seu arquivo de configuração. Mas isso só pode ser visto a partir do console ndash profimedica 31 de agosto 16 às 5:55 Soluções propostas com BeginOutputReadLine () são uma boa maneira, mas em situações como essa, não é aplicável, porque o processo (certamente com o uso de WaitForExit ()) Sai antes da saída assíncrona concluída completamente. Então, eu tentei implementá-lo de forma síncrona e descobriu que a solução é usar o método Peek () da classe StreamReader. Eu adicionei check para Peek () gt -1 para garantir que não seja o fim do stream como no artigo MSDN descrito e, finalmente, ele funciona e parar de suspender Aqui está o código: respondido 29 de abril 13 às 10:50 Eu apenas implementei isso Mudança e meu processo ainda está pendurado no processo. StandardError. ReadLine (). Ndash ganders 6 de junho 13 às 20:38 ganders pode ser seu processo. StandardError. ReadLine () retorna null ndash Fedor 6 de junho 13 às 21:33 I39ll tentar esse cheque e informá-lo. Ndash ganders 7 de junho 13 às 12:18 Eu reparei, mas eu implementei algo que alguém respondeu de uma pergunta diferente, aqui é o link para a resposta que usei: stackoverflowquestions139593hellip ndash ganders 25 de junho 13 às 12:21 Obrigado por responder . Tenho medo de que isso não funcionasse, ele ainda estava pendurado logo que chegou a 39StandardError. ReadToEnd () 39. Eu até tentei usar 39BeginErrorReadLine () 39, mas também pendurado. A única coisa que DID funcionou foi adicionar um tempo limite para 39WaitForExit39. Uma vez que este argumento específico que trava sempre dá um resultado quase que imediato, expirai em cerca de 3 segundos e tudo funciona bem. Não é muito elegante, mas funciona. Obrigado novamente por ajudar. Ndash Elad Avron 25 de agosto 11 às 8:17 Eu tive o mesmo problema de impasse. Este trecho de código funcionou para mim. Respondeu Feb 3 15 às 12:19 E quanto a algo como: respondeu 25 de novembro 15 às 7:12 Eu tive o mesmo tipo de problema que o erro estava pendurado. Com base na sua resposta a Daniel Hilgarth, nem tentei usar esses códigos, embora eu pense que eles teriam funcionado para mim. Uma vez que eu quero poder fazer uma saída ainda mais fantástica, finalmente eu decidi que eu faria isso com as duas saídas sendo feitas em uma linha de fundo. Isso funcionou para mim e me permitiu não ter que usar um tempo limite para a leitura. Respondeu Apr 4 13 às 9:57 Algo que é elegante e trabalhou para mim é: Esta resposta eu encontrei aqui e o truque é usar Flush () e Close () na entrada padrão. Respondeu 18 de março 15 às 9:39 A solução de respostas aceitas não funcionou para mim. Eu tive que usar tarefas para evitar o impasse: Com uma função GetStreamOutput da seguinte maneira: respondeu 10 de julho 15 às 15:59 Apenas no caso de alguém se tropeçar com esta pergunta enquanto estiver usando Windows Forms e TextBox (ou RichTextBox) para mostrar o Erros e saídas do processo retorna em tempo real (como eles são escritos para process. StandardOutput process. StandardError). Você precisa usar OutputDataReceived () ErrorDataReceived () para ler ambos os fluxos sem deadlocks, não há nenhuma maneira (tanto quanto eu sei) para evitar deadlocks de outra forma, mesmo a resposta do Fedors, que agora contém a tag Answer e a maioria gosta Até à data, não faz o truque para mim. No entanto, quando você usa o RichTextBox (ou TextBox) para enviar os dados, outro problema que você encontra é como realmente gravar os dados na caixa de texto em tempo real (uma vez que ele chega). Você recebe o acesso aos dados dentro de um dos segmentos de fundo OutputDataReceived () ErrorDataReceived () e você só pode anexar o texto () do thread principal. O que eu tentei pela primeira vez era chamar processo. Iniciar () de uma linha de fundo e, em seguida, chamar BeginInvoke () gt AppendText () em OutputDataReceived () ErrorDataReceived () threads enquanto o thread principal era process. WaitForExit (). No entanto, isso levou a minha forma a congelar e finalmente pendurar por toda a eternidade. Depois de alguns dias de tentativa, acabei com a solução abaixo, que parece funcionar muito bem. Em breve, você precisa adicionar as mensagens para uma coleção simultânea dentro dos segmentos OutputDataReceived () ErrorDataReceived () enquanto o tópico principal deve tentar constantemente extrair as mensagens dessa coleção e anexá-las à caixa de texto: a única desvantagem dessa abordagem é o fato Que você pode perder mensagens em um caso bastante raro, quando o processo começa a escrevê-las entre process. Start () e process. BeginErrorReadLine () process. BeginOutputReadLine (). Mantenha isso em mente. A única maneira de evitar isso é ler os fluxos completos e (ou) obter acesso a eles somente quando o processo terminar. Respondeu 24 de maio 16 às 13: 21Hi, estou desenvolvendo um aplicativo de consola C que inicia uma linha de comando e obtém alguns dados através de outro comando (o que é irrelevante nesta discussão). Eventualmente, vou obter alguns dados na linha de comando e eu só preciso apenas da última linha disso. Eu usei o seguinte código: Process. StartInfo. FileName quotcmd. exequot Process. StartInfo. RedirectStandardInput true Process. StartInfo. RedirectStandardOutput true Eu usei o Process. StandardInput. WriteLine para escrever os comandos que eu preciso para o console. Mas se Process. StartInfo. RedirectStandardOutput é verdade, não estou obtendo o resultado desejado usando a instrução Process. StandardOutput. ReadToEnd (). Split (n) Enquanto a opção ReadLine está funcionando bem e eu estou recebendo a primeira linha do texto exibido. Uma vez que todas as vezes que os dados que recebo no console difere, não consigo codificar qualquer ação específica de onde obter minha saída. Mesmo que eu coloquei um relógio na declaração Process. StandardOutput. ReadToEnd (). Split (n) Estou recebendo uma exceção de Tempo limite de Função. Por favor me ajude com esse problema. Quinta-feira, 07 de agosto de 2008 5:44 AM Então copiei o código de Manjus. Myprocesss quotcmd. exequot. Primeiro, enviei o comando quotipconfigquot, com um readToEnd () Timed out. Tentou ler em blocos, também falhou. Tentou waitForInputIddle (), mas esqueceu cmd sem interface gráfica, falhou também. Então eu precisava do cmd para terminar o fluxo se eu quisesse lê-lo. Ok então saia Então eu tentei enviar TODOS OS MEUS COMUNES, INCLUINDO primeiro o comando de saída, depois lendo. SIn. WriteLine (quotipconfigquot) sIn. WriteLine (quotipconfig allquot) sIn. WriteLine (quotexitquot) string strOutPut sOut. ReadToEnd () Funciona como um encanto. Meu ReadToEnd () retorna uma string em meio segundo, e eu obtive todas as informações que eu preciso. -) Isso poderia ser de alguma ajuda para você, Gauri O improvável que fazemos, o impossível demora um pouco mais. - Steven Parker Marcado como resposta por Jack 321 segunda-feira, 11 de agosto de 2008 5:44 AM quinta-feira, 07 de agosto de 2008 7:51 AM ReadToEnd () é capaz de causar impasse, especialmente quando você o codifica após um WaitForExit () ou envia Muita entrada. O processo está escrevendo sua saída para um buffer, que o buffer não é muito grande (2KB, eu acho). Você não lê o conteúdo deste buffer, digamos com o ReadLine (), o processo irá parar, esperando que o buffer seja esvaziado. Seu programa, por sua vez, irá parar, pois o WaitForExit () nunca retornará ou a chamada WriteLine () será interrompida, já que o processo não está mais a ler a entrada. Se esse for seu cenário, você precisará ler de forma assíncrona com BeginOutputReadLine (). Hans Passant. Marcado como resposta por Jack 321 segunda-feira, 11 de agosto de 2008 5:44 AM quinta-feira, 07 de agosto de 2008 12:13 PM Todas as respostas Você também precisa definir Process. StartInfo. UseShellExecute como falso. Marcado como resposta por Jack 321 segunda-feira, 11 de agosto de 2008 5:43 AM O que há acima é uma resposta padrão muito boa, no entanto. Eu não acho que o quotcmdquot termina o fluxo. Não há nada enviado a partir do cmd-box para indicar que o fluxo está encerrado. Considere uma página da Web que você carrega, uma vez que o código html inteiro chegou ao seu PC, o fluxo está pronto. Mesmo com a leitura de um arquivo, uma vez que você alcançou o último personagem, o fluxo está pronto. No entanto, com cmd, o fluxo não é quotdonequot. Ele apenas espera uma nova entrada, então, se você der um outro comando, ele terá a saída novamente. Hmm, eu parece ter problemas para me expressar em inglês novamente, minhas desculpas. De qualquer forma, não penso em nada que você possa fazer para usar ReadToEnd () em um cmd-output-stream, a menos que você envie o comando quotexitquot. Você tentou combinar o readline () com um. Uma análise da linha (ou seja, você obtém linhas vazias) ou b. O comando Process. WaitForIddleInput () O improvável que fazemos, o impossível demora um pouco mais. - Steven Parker quinta-feira, 07 de agosto de 2008 7:35 AM Caso você esteja executando o processo cmd. Relembre-se para escrever quotEXITquot no fluxo de entrada Quinta-feira, 07 de agosto de 2008 7:51 AM Então copiei o código do Manjus. Myprocesss quotcmd. exequot. Primeiro, enviei o comando quotipconfigquot, com um readToEnd () Timed out. Tentou ler em blocos, também falhou. Tentou waitForInputIddle (), mas esqueceu cmd sem interface gráfica, falhou também. Então eu precisava do cmd para terminar o fluxo se eu quisesse lê-lo. Ok então saia Então eu tentei enviar TODOS OS MEUS COMUNES, INCLUINDO primeiro o comando de saída, depois lendo. SIn. WriteLine (quotipconfigquot) sIn. WriteLine (quotipconfig allquot) sIn. WriteLine (quotexitquot) string strOutPut sOut. ReadToEnd () Funciona como um encanto. Meu ReadToEnd () retorna uma string em meio segundo, e eu obtive todas as informações que eu preciso. -) Isso poderia ser de alguma ajuda para você, Gauri O improvável que fazemos, o impossível demora um pouco mais. - Steven Parker Marcado como resposta por Jack 321 segunda-feira, 11 de agosto de 2008 5:44 AM quinta-feira, 07 de agosto de 2008 7:51 AM ReadToEnd () é capaz de causar impasse, especialmente quando você o codifica após um WaitForExit () ou envia Muita entrada. O processo está escrevendo sua saída para um buffer, que o buffer não é muito grande (2KB, eu acho). Você não lê o conteúdo deste buffer, digamos com o ReadLine (), o processo irá parar, esperando que o buffer seja esvaziado. Seu programa, por sua vez, irá parar, pois o WaitForExit () nunca retornará ou a chamada WriteLine () será interrompida, já que o processo não está mais a ler a entrada. Se esse for seu cenário, você precisará ler de forma assíncrona com BeginOutputReadLine (). Hans Passant. Marcado como resposta por Jack 321 segunda-feira, 11 de agosto de 2008 5:44 AM Quinta-feira, 07 de agosto de 2008 12:13 PM A Microsoft está realizando 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ê deixar o site Msdn. Você gostaria de participar
Comments
Post a Comment