пятница, 6 апреля 2018 г.

Processo de diagnóstico do sistema waitforexit c #


System. diagnostics. process waitforexit c #
Então eu tenho lutado contra esse problema por algum tempo 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, ele está imprimindo 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 resto do seu aplicativo está "bloqueado" em um estado onde 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:

System. diagnostics. process waitforexit c #
Eu tenho trabalhado no meu projeto da empresa. Eu notei esse problema, quando eu chamo de um Exe para outro Exe. Durante o arrasto do formulário no segundo Exe, ele mostrará vários formulários. Eu estou usando WaitforExit ().
por favor resolva.
Esta é exatamente a causa do problema. Se WaitForExit é chamado do thread do formulário, ele impedirá que o formulário seja redesenhado. Arrastar algo na frente de uma janela bloqueada deixa um rastro da janela arrastada.
Sugerido como Resposta ahmedilyas Moderador quinta-feira, 28 de julho de 2011 10:34 Marcado como Resposta Jackie-Sun Moderador segunda-feira, 8 de agosto de 2011 6:50.
O código seria melhor e também seria melhor se você pudesse nos dizer exatamente o que está tentando alcançar.
O WaitForExit () simplesmente espera (bloqueia seu código por este período) para um processo sair antes de continuar com a execução do seu código de chamada.
C # MVP (2007-2010) MS Vendor - MS Todo o caminho! Seguidor desde 1995 MS Super Evangelist | Moderador dos fóruns do MSDN.
Sugerido como Resposta ahmedilyas Moderador quinta-feira, 28 de julho de 2011 10:33 Marcado como Resposta Jackie-Sun Moderador segunda-feira, 8 de agosto de 2011 6:50.
Todas as respostas.
O código seria melhor e também seria melhor se você pudesse nos dizer exatamente o que está tentando alcançar.
O WaitForExit () simplesmente espera (bloqueia seu código por este período) para um processo sair antes de continuar com a execução do seu código de chamada.
C # MVP (2007-2010) MS Vendor - MS Todo o caminho! Seguidor desde 1995 MS Super Evangelist | Moderador dos fóruns do MSDN.
Sugerido como Resposta ahmedilyas Moderador quinta-feira, 28 de julho de 2011 10:33 Marcado como Resposta Jackie-Sun Moderador segunda-feira, 8 de agosto de 2011 6:50.
Eu tinha check. it tem problema em waitforexit () only. i notei que o problema ao mover segundo formulário exe.
o que exatamente é o problema? você leu minha resposta? você também leu o link que eu havia fornecido?
WaitForExit () é um método de bloqueio de threads que fará exatamente isso - espere que um processo saia antes que ele continue com seu código. ele NÃO fará com que seu formulário seja ocultado ou minimizado, a menos que você diga ao seu código para fazer isso antes de chamar WaitForExit ()
C # MVP (2007-2010) MS Vendor - MS Todo o caminho! Seguidor desde 1995 MS Super Evangelist | Moderador dos fóruns do MSDN.
Tudo está funcionando bem. mas quando eu movo o formulário, ele mostra várias formas.
Esta é exatamente a causa do problema. Se WaitForExit é chamado do thread do formulário, ele impedirá que o formulário seja redesenhado. Arrastar algo na frente de uma janela bloqueada deixa um rastro da janela arrastada.
Sugerido como Resposta ahmedilyas Moderador quinta-feira, 28 de julho de 2011 10:34 Marcado como Resposta Jackie-Sun Moderador segunda-feira, 8 de agosto de 2011 6:50.
quando você diz mostrando vários formulários - você está falando sobre várias instâncias dos formulários ou apenas o desenho / renderização?
se for o desenho / renderização, então sim, como foi dito antes - é porque ele está esperando o processo sair / terminar antes de continuar e é threadblocking, então você verá o problema & quot; problem & quot; você está parecendo estar descrevendo. Não há & quot; corrigir & quot; por isso, como não é um bug ou um problema, mas apenas o que você está usando e como você está usando.
Existe uma razão pela qual você está usando WaitForExit ()? Você tem que mostrar seu formulário quando você está usando WaitForExit ()? Por que você não esconde ou minimiza o formulário antes de chamar WaitForExit () e restaurá-lo depois?
C # MVP (2007-2010) MS Vendor - MS Todo o caminho! Seguidor desde 1995 MS Super Evangelist | Moderador dos fóruns do MSDN.

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 Process 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.

Classe de processo.
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.
Fornece acesso a processos locais e remotos e permite iniciar e interromper processos do sistema local.
Para procurar o código-fonte do. NET Framework para esse tipo, consulte a fonte de referência.
Assembly: System (no System. dll)
Inicializa uma nova instância da classe Process.
Obtém a prioridade básica do processo associado.
Obtém um valor indicando se o componente pode gerar um evento (herdado do componente).
Obtém o IContainer que contém o componente. (Herdado do componente.)
Obtém um valor que indica se o componente está atualmente no modo de design. (Herdado do componente.)
Obtém ou define se o evento Exited deve ser gerado quando o processo é finalizado.
Obtém a lista de manipuladores de eventos que estão anexados a este componente. (Herdado do componente.)
Obtém o valor que o processo associado especificou quando foi finalizado.
Obtém o tempo que o processo associado foi encerrado.
Obtém o identificador nativo do processo associado.
Obtém o número de identificadores abertos pelo processo.
Obtém um valor indicando se o processo associado foi finalizado.
Obtém o identificador não identificado para o processo associado.
Obtém o nome do computador no qual o processo associado está sendo executado.
Obtém o módulo principal do processo associado.
Obtém o identificador de janela da janela principal do processo associado.
Obtém a legenda da janela principal do processo.
Obtém ou define o tamanho máximo permitido do conjunto de trabalho, em bytes, para o processo associado.
Obtém ou define o tamanho mínimo permitido do conjunto de trabalho, em bytes, para o processo associado.
Obtém os módulos que foram carregados pelo processo associado.
Obsoleto. Obtém a quantidade de memória do sistema não paginada, em bytes, alocada para o processo associado.
Obtém a quantidade de memória do sistema não paginada, em bytes, alocada para o processo associado.
Obsoleto. Obtém a quantidade de memória paginada, em bytes, alocada para o processo associado.
Obtém a quantidade de memória paginada, em bytes, alocada para o processo associado.
Obsoleto. Obtém a quantidade de memória do sistema paginável, em bytes, alocada para o processo associado.
Obtém a quantidade de memória do sistema paginável, em bytes, alocada para o processo associado.
Obsoleto. Obtém a quantidade máxima de memória no arquivo de paginação da memória virtual, em bytes, usada pelo processo associado.
Obtém a quantidade máxima de memória no arquivo de paginação da memória virtual, em bytes, usada pelo processo associado.
Obsoleto. Obtém a quantidade máxima de memória virtual, em bytes, usada pelo processo associado.
Obtém a quantidade máxima de memória virtual, em bytes, usada pelo processo associado.
Obsoleto. Obtém o tamanho do conjunto de trabalho de pico para o processo associado, em bytes.
Obtém a quantidade máxima de memória física, em bytes, usada pelo processo associado.
Obtém ou define um valor indicando se a prioridade do processo associado deve ser temporariamente aumentada pelo sistema operacional quando a janela principal tiver o foco.
Obtém ou define a categoria de prioridade geral para o processo associado.
Obsoleto. Obtém a quantidade de memória privada, em bytes, alocada para o processo associado.
Obtém a quantidade de memória privada, em bytes, alocada para o processo associado.
Obtém o tempo de processador privilegiado para este processo.
Obtém o nome do processo.
Obtém ou define os processadores nos quais os threads neste processo podem ser planejados para serem executados.
Obtém um valor indicando se a interface do usuário do processo está respondendo.
Obtém o identificador nativo para esse processo.
Obtém o identificador de sessão dos Serviços de Terminal para o processo associado.
Obtém ou define o ISite do componente. (Herdado do componente.)
Obtém um fluxo usado para ler a saída de erro do aplicativo.
Obtém um fluxo usado para gravar a entrada do aplicativo.
Obtém um fluxo usado para ler a saída textual do aplicativo.
Obtém ou define as propriedades para passar para o método Start do processo.
Obtém o tempo que o processo associado foi iniciado.
Obtém ou define o objeto usado para empacotar as chamadas do manipulador de eventos que são emitidas como resultado de um evento de saída do processo.
Obtém o conjunto de threads que estão sendo executados no processo associado.
Obtém o tempo total do processador para este processo.
Obtém o tempo do processador do usuário para este processo.
Obsoleto. Obtém o tamanho da memória virtual do processo, em bytes.
Obtém a quantidade da memória virtual, em bytes, alocada para o processo associado.
Obsoleto. Obtém o uso da memória física do processo associado, em bytes.
Obtém a quantidade de memória física, em bytes, alocada para o processo associado.
Inicia operações de leitura assíncrona no fluxo StandardError redirecionado do aplicativo.
Inicia operações de leitura assíncrona no fluxo StandardOutput redirecionado do aplicativo.
Cancela a operação de leitura assíncrona no fluxo StandardError redirecionado de um aplicativo.
Cancela a operação de leitura assíncrona no fluxo StandardOutput redirecionado de um aplicativo.
Libera todos os recursos associados a esse componente.
Fecha um processo que possui uma interface de usuário enviando uma mensagem de fechamento para sua janela principal.
Cria um objeto que contém todas as informações relevantes necessárias para gerar um proxy usado para se comunicar com um objeto remoto. (Herdado de MarshalByRefObject.)
Libera todos os recursos usados ​​pelo Componente. (Herdado do Componente.)
Essa API suporta a infraestrutura do produto e não se destina a ser usada diretamente em seu código. Libere todos os recursos usados ​​por esse processo. (Substitui Component. Dispose (Boolean).)
Coloca um componente de Processo no estado para interagir com os processos do sistema operacional executados em um modo especial, ativando a propriedade nativa SeDebugPrivilege no encadeamento atual.
Determina se o objeto especificado é igual ao objeto atual. (Herdado de Object.)
Libera recursos não gerenciados e executa outras operações de limpeza antes que o componente seja recuperado pela coleta de lixo. (Herdado do componente.)
Obtém um novo componente Process e o associa ao processo atualmente ativo.
Serve como a função hash padrão. (Herdado de Object.)
Recupera o objeto de serviço de vida útil atual que controla a diretiva de tempo de vida para essa instância. (Herdado de MarshalByRefObject.)
Retorna um novo componente Process, dado o identificador de um processo no computador local.
Retorna um novo componente Process, dado um identificador de processo e o nome de um computador na rede.
Cria um novo componente de processo para cada recurso de processo no computador local.
Cria um novo componente de processo para cada recurso de processo no computador especificado.
Cria uma matriz de novos componentes do processo e os associa a todos os recursos do processo no computador local que compartilham o nome do processo especificado.
Cria uma matriz de novos componentes do processo e os associa a todos os recursos do processo em um computador remoto que compartilha o nome do processo especificado.
Retorna um objeto que representa um serviço fornecido pelo Componente ou por seu Container. (Herdado do Componente.)
Obtém o Type da instância atual. (Herdado de Object.)
Obtém um objeto de serviço vitalício para controlar a diretiva de tempo de vida para essa instância. (Herdado de MarshalByRefObject.)
Imediatamente interrompe o processo associado.
Retira um componente de Processo do estado que permite interagir com processos do sistema operacional executados em um modo especial.
Cria uma cópia superficial do objeto atual. (Herdado de Object.)
Cria uma cópia superficial do objeto MarshalByRefObject atual. (Herdado de MarshalByRefObject.)
Gera o evento Exited.
Descarta qualquer informação sobre o processo associado que foi armazenado em cache dentro do componente do processo.
Inicia (ou reutiliza) o recurso de processo especificado pela propriedade StartInfo desse componente de processo e o associa ao componente.
Inicia o recurso de processo especificado pelo parâmetro que contém as informações de início do processo (por exemplo, o nome do arquivo do processo a ser iniciado) e associa o recurso a um novo componente do Processo.
Inicia um recurso de processo especificando o nome de um documento ou arquivo de aplicativo e associa o recurso a um novo componente de processo.
Inicia um recurso de processo especificando o nome de um aplicativo e um conjunto de argumentos de linha de comando e associa o recurso a um novo componente de processo.
Inicia um recurso de processo especificando o nome de um aplicativo, um nome de usuário, uma senha e um domínio e associa o recurso a um novo componente de processo.
Inicia um recurso de processo especificando o nome de um aplicativo, um conjunto de argumentos da linha de comandos, um nome de usuário, uma senha e um domínio e associa o recurso a um novo componente do processo.
Formata o nome do processo como uma string, combinada com o tipo de componente pai, se aplicável. (Substitui Component. ToString ().)
Instrui o componente Process a aguardar indefinidamente que o processo associado seja encerrado.
Instrui o componente Processo a aguardar o número especificado de milissegundos para o processo associado sair.
Faz com que o componente Process espere indefinidamente que o processo associado entre em um estado inativo. Essa sobrecarga aplica-se apenas aos processos com uma interface com o usuário e, portanto, um loop de mensagem.
Faz com que o componente Process aguarde o número especificado de milissegundos para que o processo associado entre em um estado inativo. Essa sobrecarga aplica-se apenas aos processos com uma interface com o usuário e, portanto, um loop de mensagem.
Ocorre quando o componente é descartado por uma chamada para o método Dispose. (Herdado do componente).
Ocorre quando um aplicativo grava em seu fluxo StandardError redirecionado.
Ocorre quando um processo sai.
Ocorre toda vez que um aplicativo grava uma linha em seu fluxo StandardOutput redirecionado.
Para exibir o código-fonte do. NET Framework para esse tipo, consulte a fonte de referência. Você pode navegar pelo código-fonte on-line, fazer o download da referência para visualização off-line e percorrer as fontes (incluindo correções e atualizações) durante a depuração; veja instruções.
Um componente de processo fornece acesso a um processo que está sendo executado em um computador. Um processo, nos termos mais simples, é um aplicativo em execução. Um thread é a unidade básica na qual o sistema operacional aloca o tempo do processador. Um thread pode executar qualquer parte do código do processo, incluindo partes atualmente sendo executadas por outro thread.
O componente Processo é uma ferramenta útil para iniciar, parar, controlar e monitorar aplicativos. Você pode usar o componente Process, para obter uma lista dos processos em execução ou iniciar um novo processo. Um componente de processo é usado para acessar processos do sistema. Depois que um componente de processo foi inicializado, ele pode ser usado para obter informações sobre o processo em execução. Essas informações incluem o conjunto de threads, os módulos carregados (arquivos. dll e. exe) e informações de desempenho, como a quantidade de memória que o processo está usando.
Este tipo implementa a interface IDisposable. Quando você terminar de usar o tipo, você deve descartá-lo direta ou indiretamente. Para descartar o tipo diretamente, chame seu método Dispose em um bloco try / catch. Para descartá-lo indiretamente, use uma construção de linguagem, como usando (em C #) ou usando (no Visual Basic). Para obter mais informações, consulte a seção “Usando um objeto que implementa IDisposable” no tópico interface IDisposable.
Processos de 32 bits não podem acessar os módulos de um processo de 64 bits. Se você tentar obter informações sobre um processo de 64 bits de um processo de 32 bits, você receberá uma exceção Win32Exception. Um processo de 64 bits, por outro lado, pode acessar os módulos de um processo de 32 bits.
O componente do processo obtém informações sobre um grupo de propriedades de uma só vez. Depois que o componente Process tiver obtido informações sobre um membro de qualquer grupo, ele armazenará em cache os valores das outras propriedades nesse grupo e não obterá novas informações sobre os outros membros do grupo até você chamar o método Refresh. Portanto, não é garantido que um valor de propriedade seja mais recente que a última chamada para o método Refresh. As desagregações de grupo são dependentes do sistema operacional.
Se você tiver uma variável de caminho declarada em seu sistema usando aspas, deverá qualificar totalmente esse caminho ao iniciar qualquer processo encontrado nesse local. Caso contrário, o sistema não encontrará o caminho. Por exemplo, se c: \ mypath não estiver em seu caminho e você adicioná-lo usando aspas: path =% path%; "c: \ mypath", você deve qualificar totalmente qualquer processo em c: \ mypath ao iniciá-lo.
Um processo do sistema é identificado de maneira não identificada no sistema por seu identificador de processo. Como muitos recursos do Windows, um processo também é identificado pelo seu identificador, o que pode não ser feito no computador. Um identificador é o termo genérico para um identificador de um recurso. O sistema operacional persiste o identificador do processo, que é acessado por meio da propriedade Handle do componente Process, mesmo quando o processo foi encerrado. Assim, você pode obter informações administrativas do processo, como o ExitCode (geralmente zero para o sucesso ou um código de erro diferente de zero) e o ExitTime. As alças são um recurso extremamente valioso, portanto, vazar alças é mais virulento do que vazar memória.
Essa classe contém uma demanda de link e uma demanda de herança no nível de classe que se aplica a todos os membros. Uma SecurityException é lançada quando o chamador imediato ou a classe derivada não tem permissão de confiança total. Para detalhes sobre demandas de segurança, consulte Demandas de link.
No. NET Framework na área de trabalho, a classe Process usa, por padrão, codificações de console, que normalmente são codificações de página de código, para os fluxos de entrada, saída e erro. Por exemplo código, em sistemas cuja cultura é o inglês (Estados Unidos), a página de código 437 é a codificação padrão para a classe Console. No entanto, o. NET Core pode disponibilizar apenas um subconjunto limitado dessas codificações. Se este for o caso, ele usa Encoding. UTF8 como a codificação padrão.
Se um objeto Processar depender de codificações de páginas de códigos específicas, você ainda poderá disponibilizá-las fazendo o seguinte antes de chamar qualquer método Process:
Adicione uma referência ao assembly System. Text. Encoding. CodePages. dll ao seu projeto.
Passe o objeto EncodingProvider para a codificação. Método RegisterProvider para disponibilizar as codificações adicionais suportadas pelo provedor de codificação.
A classe Process usará automaticamente a codificação padrão do sistema em vez de UTF8, desde que você tenha registrado o provedor de codificação antes de chamar qualquer método Process.

Propriedade Process. StandardOutput.
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.
Obtém um fluxo usado para ler a saída textual do aplicativo.
Assembly: System (no System. dll)
Valor da propriedade.
Um StreamReader que pode ser usado para ler o fluxo de saída padrão do aplicativo.
O fluxo StandardOutput foi aberto para operações de leitura assíncrona com BeginOutputReadLine.
Quando um processo grava texto em seu fluxo padrão, esse texto é normalmente exibido no console. Ao redirecionar o fluxo StandardOutput, você pode manipular ou suprimir a saída de um processo. Por exemplo, você pode filtrar o texto, formatá-lo de maneira diferente ou gravar a saída no console e em um arquivo de log designado.
Para usar o StandardOutput, você deve definir ProcessStartInfo. UseShellExecute como false e deve definir ProcessStartInfo. RedirectStandardOutput como true. Caso contrário, a leitura do fluxo StandardOutput gerará uma exceção.
O fluxo StandardOutput redirecionado pode ser lido de forma síncrona ou assíncrona. Métodos como Read, ReadLine e ReadToEnd executam operações de leitura síncrona no fluxo de saída do processo. Essas operações de leitura síncrona não são concluídas até que o Processo associado grave em seu fluxo StandardOutput ou feche o fluxo.
Por outro lado, BeginOutputReadLine inicia operações de leitura assíncrona no fluxo StandardOutput. Esse método ativa um manipulador de eventos designado para a saída do fluxo e retorna imediatamente ao responsável pela chamada, que pode executar outro trabalho enquanto a saída do fluxo é direcionada para o manipulador de eventos.
As operações de leitura síncrona introduzem uma dependência entre a leitura do responsável pela chamada do fluxo StandardOutput e a gravação do processo filho nesse fluxo. Essas dependências podem resultar em condições de deadlock. Quando o chamador lê o fluxo redirecionado de um processo filho, ele depende do filho. O chamador aguarda na operação de leitura até que o filho grave no fluxo ou feche o fluxo. Quando o processo filho grava dados suficientes para preencher seu fluxo redirecionado, ele depende do pai. O processo filho aguarda na próxima operação de gravação até que o pai leia o fluxo completo ou feche o fluxo. A condição de deadlock resulta quando o chamador e o processo filho aguardam um ao outro para concluir uma operação e nenhum deles pode prosseguir. Você pode evitar deadlocks avaliando dependências entre o chamador e o processo filho.
O seguinte código C #, por exemplo, mostra como ler de um fluxo redirecionado e aguardar a saída do processo filho.
O exemplo de código evita uma condição de deadlock chamando p. StandardOutput. ReadToEnd antes de p. WaitForExit. Uma condição de deadlock pode resultar se o processo pai chama p. WaitForExit antes de p. StandardOutput. ReadToEnd e o processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai aguardaria indefinidamente que o processo filho fosse encerrado. O processo filho esperaria indefinidamente que o pai lesse todo o fluxo StandardOutput.
Há um problema semelhante quando você lê todo o texto da saída padrão e dos fluxos de erro padrão. O seguinte código C #, por exemplo, executa uma operação de leitura nos dois fluxos.
O exemplo de código evita a condição de deadlock executando operações de leitura assíncrona no fluxo StandardOutput. Uma condição de deadlock resulta se o processo pai chamar p. StandardOutput. ReadToEnd seguido por p. StandardError. ReadToEnd e o processo filho grava texto suficiente para preencher seu fluxo de erro. O processo pai esperaria indefinidamente que o processo filho fechasse seu fluxo StandardOutput. O processo filho esperaria indefinidamente que o pai lesse o fluxo completo do StandardError.
Você pode usar operações de leitura assíncronas para evitar essas dependências e seu potencial de deadlock. Como alternativa, você pode evitar a condição de deadlock criando dois threads e lendo a saída de cada fluxo em um thread separado.
Você não pode mesclar operações de leitura assíncrona e síncrona em um fluxo redirecionado. Depois que o fluxo redirecionado de um processo é aberto no modo assíncrono ou síncrono, todas as operações de leitura adicionais nesse fluxo devem estar no mesmo modo. Por exemplo, não siga BeginOutputReadLine com uma chamada para ReadLine no fluxo StandardOutput ou vice-versa. No entanto, você pode ler dois fluxos diferentes em modos diferentes. Por exemplo, você pode chamar BeginOutputReadLine e, em seguida, chamar ReadLine para o fluxo StandardError.

Комментариев нет:

Отправить комментарий