Redirecionamento do teclado para a espera
Как асинхронно захватывать выход процесса в powershell?
Я хочу записать stdout и stderr из процесса, который я запускаю в Powershell script, и выводить его асинхронно на консоль. Я нашел документацию по этому поводу через MSDN и другие блоги.
После создания и запуска приведенного ниже примера я не могу получить какой-либо вывод, который будет отображаться асинхронно. Весь вывод выводится только при завершении процесса.
В этом примере я ожидал увидеть вывод "oi" в командной строке до окончания выполнения программы, потому что должно было быть вызвано событие OutputDataReceived.
Я пробовал это с помощью других исполняемых файлов - java. exe, git. exe и т. д. Все они имеют одинаковый эффект, поэтому мне остается думать, что есть что-то простое, что я не понимаю или пропустили. Что еще нужно сделать для асинхронного чтения stdout?
К сожалению, асинхронное чтение не так просто, если вы хотите сделать это правильно. Если вы вызываете WaitForExit () без тайм-атта, вы можете использовать что-то вроде этой функции, которую я написал (на основе кода С #):
Он фиксирует stdout, stderr и код выхода. Пример использования:
Для получения дополнительной информации и альтернативных реализаций (на С #) прочитайте это сообщение в блоге.
На основе Ответ Александра Обершта Я создал функцию, которая использует тайм-атт и асинхронные классы задач вместо обработчиков событий. Согласно Майк Адельсон.
К сожалению, этот метод (обработчики событий) не дает возможности узнать когда последний бит данных был получен. Потому что все асинхронно, возможно (и я это наблюдал) для событий пожар после возвращения WaitForExit ().
Я не мог заставить любой из этих примеров работать с PS 4.0.
Я хотел запустить boneco aplicar из пакета polvo Implantar (через Deploy. ps1) и посмотреть вывод в режиме реального времени, а не дождаться завершения процесса (через час), поэтому я придумал следующее:
Примеры здесь полезны, но не полностью соответствуют моему варианту использования. Я не хотел вызывать команду и выйти. Я хотел открыть командную строку, отправить ввод, прочитать выход и повторить. Вот мое решение для этого.
Затем из PowerShell добавьте класс и используйте его.
Не забудьте вызвать функцию Dispose () в конце, чтобы очистить процесс, выполняющийся в фоновом режиме. Кроме того, вы можете закрыть этот процесс, выполнив что-то вроде $ cmd. RunCommand ("sair")
Ознакомьтесь с другими вопросами по меткам eventos assíncronos powershell.
System. Diagnostics. Process, RedirectStandardOutput process hanging.
Em um desenvolvimento do nosso aplicativo web interno, estávamos executando de forma síncrona aplicativos de console com certos argumentos e tentando exibir os resultados no front-end.
Quando ativamos o processo, eu consigo ver o processo ser iniciado no gerenciador de tarefas e nunca sai, após um período de tempo (configuração de tempo limite do IIS), o aplicativo da Web expira.
No final, descobrimos que o motivo é devido a uma condição de bloqueio morto entre o processo pai (w3wp) e o processo filho (aplicativo de console).
As operações de leitura síncrona introduzem uma dependência entre a leitura do chamador do fluxo StandardOutput e a escrita do processo filho para esse fluxo. Essas dependências podem resultar em condições de impasse. Quando o chamador lê do fluxo redirecionado de um processo filho, depende da criança. O chamador aguarda a operação de leitura até que a criança grava a transmissão ou encerre o fluxo. 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 processo do chamador e filho aguardam um para o outro para concluir uma operação, e nenhum deles pode prosseguir.
A solução é realmente simples, veja o snippet de código abaixo.
// Inicie o processo filho.
Processo p = novo Processo ();
// Redirecione o fluxo de saída do processo filho.
// Não espere que o processo filho saia antes.
// leitura até o final do seu fluxo redirecionado.
// Leia o fluxo de saída primeiro e depois aguarde.
string output = p. StandardOutput. ReadToEnd ();
BTW, a maioria das explicações é do MSDN, mas demorou um pouco para descobrir.
Autor: Saravana Kumar.
Saravana Kumar é o Fundador e CTO do BizTalk360, um software corporativo que atua como uma solução tudo-em-um para melhor administração, operação, suporte e monitoramento de ambientes do Microsoft BizTalk Server. Ver todas as postagens de Saravana Kumar.
C # Hoje.
Deixe o # C # hoje!
Deixe o # C # hoje!
Como evitar deadlocks ao ler o console filho redirecionado no C # 2.
A leitura da saída da criança redirecionada parece ser uma tarefa fácil. Mas há desenvolvedores que lutam com o processo infantil pendurado por causa de bloqueios de leitura / leitura de console. E os deadlocks nunca são fáceis de investigar.
Consideremos um exemplo comum - um processo pai inicia um processo filho e lê toda a saída. Aqui está um exemplo de aplicação que pode simular o cenário.
O aplicativo pode ser executado em dois modos:
Processo principal - executa o processo filho e lê seu processo de saída infantil - imprime um pouco de saída.
Tudo funciona bem, mas consideremos um cenário em que o rendimento da criança é significativo maior.
Desta vez, o processo pai irá pendurar - é um impasse. Por quê? Vamos pensar o que o pai faz - primeiro ele configura o redirecionamento de saída do processo filho.
Em seguida, inicia o processo filho.
O passo consecutivo aguarda a conclusão do processo infantil.
E esse é o ponto onde o processo pai bloqueia com a criança. Por quê? O pai está aguardando que a criança termine e a criança tenha alguma dependência do pai também.
Primeiro, você precisa entender como o redirecionamento de saída funciona. Há um buffer criado para a saída. Quando a criança está escrevendo para o console, ele realmente está escrevendo para o buffer. Se a criança escreve muito, o buffer pode ficar cheio. Nesse caso, a criança trava no Console. Write até o buffer ter algum espaço.
O pai deve ler a saída da criança antes de esperar que a criança termine. Então, para corrigir o impasse, temos que trocar as seguintes linhas.
O código pai completo deve ser mostrado abaixo.
Observe que exatamente o mesmo problema pode acontecer com a saída de erro padrão (stderr). Além disso, um impasse semelhante pode acontecer com a escrita na entrada padrão da criança.
Basicamente você precisa ter muito cuidado e entender o que você está fazendo se quiser ler a entrada / saída da criança de forma síncrona.
Deixe um comentário Cancelar resposta.
2 pensamentos sobre & ldquo; Como evitar deadlocks ao ler o console filho redirecionado em C # & rdquo;
Venceu esse impasse ainda que o processo produza muito em stderr? Eu acho que é realmente seguro, você precisa usar os eventos em vez disso.
Correto, adicionei uma nota sobre o stderr.
Eu concordo que o manuseio assíncrono é uma maneira mais segura. I & # 8217; ll escrever uma postagem sobre isso também.
Comments
Post a Comment