Saturday 17 June 2017

Contador De Desempenho C # Processo Waitforexit


Usando contadores de desempenho na linguagem C Em qualquer momento, o sistema operacional Windows está rastreando estatísticas para o sistema e muitos dos aplicativos de processos que estão atualmente sendo executados nele. Coisas como o número de processadores, quantos segmentos estão sendo executados, a freqüência do CLR na coleta de lixo, o número de operações de IO que estão sendo executadas, etc, são rastreados através de chamados contadores de desempenho. Uma maneira de você olhar esses vários contadores é olhar para eles através do programa Performance Monitor8230 também conhecido como perfmon. exe. Se você for ao botão Iniciar (no Windows 7 ou versões similares do Windows) e na caixa de execução, digite 8220perfmon. exe8221, você deve ver o Monitor de desempenho aparecer. Lá você pode explorar os vários contadores disponíveis para você. A estrutura dos contadores e categorias de desempenho Em muitos textos que você pode ter lido, eles sempre estruturam o sistema como uma lista de categorias (como Sistema, Servidor, Processador, Memória CLR NET, etc.) e, nessas categorias, você possui contadores semelhantes agrupados. Por exemplo, na categoria Processor, você teria contadores relacionados a informações sobre sua CPU e seus núcleos. Uma coisa que eu acho que a maioria dos textos que don8217t faz é explicar um relacionamento direto com a idéia de 8220instentes8221. Para ler os contadores 8220most8221, você precisa ter uma instância para uma determinada categoria. Então, em vez de ser uma categoria, um contador e, em seguida, várias instâncias, é mais como categoria, zero ou mais instâncias para as quais os contadores dessa categoria podem ser aplicados. Isso significa que uma categoria de contador pode ter contadores que, se não houver instâncias para esse tipo de categoria, são relativamente inutilizáveis ​​em qualquer ponto no tempo. Como exemplo, let8217s leva a categoria CLR de desempenho. Esta categoria fornece contadores relacionados a aplicativos e suas estatísticas de memória CLR. Se eu estiver executando o meu aplicativo de teste, veria uma instância do exe pop-up nesta categoria da memória CLR. Eu poderia então poder aplicar contadores para ver quanto tempo ele gasta objetos de coleta de lixo, o número de alças que ele usa, o número de coleções Gen 0, etc. Mas se eu não tivesse nenhuma instância em execução, essa categoria não seria Muito uso. Eu não precisaria ter uma instância para aplicar contadores para. Categorias como o Processador sempre devem ter instâncias porque elas se aplicam à sua CPU, que certamente você tem um ou mais. Se você estiver executando um computador quad core, você veria 4 instâncias lá, cada um tem o mesmo conjunto de contadores que estão sendo aplicados a eles. A razão pela qual eu estou explicando isso é que, no nosso código abaixo, temos que verificar instâncias antes de tentar ler alguns contadores. Caso contrário, podemos ter problemas em que estamos tentando ler o desempenho de uma instância que não executa nada. Por que precisamos de contadores de desempenho As informações amarradas em um desses contadores podem nos dar uma visão de nossos aplicativos e do sistema para o qual seu programa pode estar em execução. Podemos verificar se há memória disponível suficiente, podemos verificar se o computador está usando vários núcleos de CPU, podemos saber se talvez nosso aplicativo esteja usando muitos recursos e liberar algumas coisas, etc. Com esses contadores, podemos avaliar a saúde geral Da nossa aplicação e do sistema como um todo. E antes de perguntar, sim, você pode alcançar esse tipo de informação usando outros meios, como o sistema WMI (Windows Management Instrumentation) ou através de alguns objetos nativos. No entanto, os contadores podem ser um mecanismo para avaliar as estatísticas de tempo de execução atuais e alcançar muitas coisas que podem ser impossíveis ou difíceis de ler usando outros métodos. Lendo um contador usando C Antes de começar com o nosso código, tente abrir o Monitor de desempenho agora e navegue pelas várias categorias e contadores. Para o nosso código, vamos escolher um simples que irá mostrar-lhe como as coisas funcionam. Nosso exemplo irá ler 8220Bytes Receivedsec8221 da nossa principal conexão de interface de rede ativa (NIC). Vamos configurá-lo para pesquisar a NIC para a nossa estatística a cada segundo por vinte segundos. Como nossas conexões normalmente geralmente estão recebendo algum tipo de informação nos dias de hoje, você deve ver números quase que imediatamente. Caso contrário, você pode apenas abrir um navegador enquanto isso está sendo executado e navegar até um site para começar a ver os números mudarem. O contador de desempenho de leitura envolve o uso da classe PerformanceCounter que você pode encontrar no namespace System. Diagnostics. Leva a categoria, o nome do contador e, opcionalmente, uma instância. No nosso exemplo, estamos especificando a categoria da Interface de Rede, vamos querer ver a conta Bytes Receivedsec da nossa instância NIC8230 ativa. Para puxar um valor do contador, estamos usando o método NextValue () e imprimi-lo para a janela do console para que possamos ver o que está sendo exibido. Então, dormimos por um segundo e voltemos para tomar nossa próxima leitura. Este método particular não é ideal, pois se você tirasse isso em uma forma, pois você acabaria bloqueando seu segmento principal por 20 segundos, mas é ótimo como uma explicação simples. A partir desta estrutura, você pode ver que esses contadores são feitos para serem consultados repetidamente para formar coisas como um gráfico, e é por isso que você vê esse gráfico no monitor de desempenho. Misturando essa idéia com algo como um thread de fundo de monitoramento e você tem uma configuração para ler dados estatísticos enquanto o usuário faz alguma outra coisa. Criando contadores e escrevendo dados para eles Talvez você tenha suas próprias estatísticas que você deseja manter em algum momento para sua aplicação. Você pode criar esses contadores de forma programática usando o CounterCreationDataCollection. Aqui, adicionamos novos contadores criando uma instância de CounterCreationData (), especificando o nome do contador, informações de ajuda e o tipo de contador subjacente (como se fosse NumberOfItems32). Uma vez que adicionamos todos os nossos contadores à coleção, passamos o nome e a coleção da categoria para o método PerformanceCounterCategory. Create () para criá-lo. Nota: Você pode precisar de privilégios de administrador neste momento para adicionar a categoria. Normalmente, você não gostaria de adicionar sua própria categoria a menos que você inicialmente configurasse um programa. Neste ponto você obtém as permissões adequadas e, em seguida, crie os contadores. Acho que, na maioria das vezes, tudo o que sempre preciso fazer é ler contadores existentes. A partir do nosso código acima, você pode ver como as etapas avançam de verificar se a categoria já existe até a criação da categoria. Se uma categoria existir, você terá que excluir a categoria primeiro antes de poder criá-la novamente (usando o método PerformanceCounterCategory. Delete). Portanto, o código acima também pode incluir algum tipo de declaração que pode excluir a categoria antes de criar a coleção. Por fim, Manipulando seus contadores criados Esta parte é bastante direta. Uma vez que você criou seus contadores personalizados, você só precisa usar a classe PerformanceCounter novamente para ler o contador, mas defina sua propriedade 8220ReadOnly8221 como falsa para que você possa definir sua propriedade. RawValue para algum valor. Você também pode incrementar o valor usando métodos como Increment () ou IncrementBy () para incrementá-lo por algum valor fixo. Mais uma vez, certifique-se de ter os privilégios de administrador adequados primeiro se você estiver encontrando um muro aqui. Algumas Gotchas para evitar Ao jogar com contadores, você pode encontrar alguns problemas estranhos e eu só queria ter certeza de que estava ciente deles. Um dos primeiros que você pode encontrar é envolver a leitura de um contador específico. O contador pode inicialmente sair zero no início. Isso ocorre porque os contadores são baseados na leitura de um valor anterior para calcular seu valor atual. Como não há valor prévio na primeira amostra, ele sai de zero. O próximo valor pull deve então começar a ter um valor. Outro getcha, que abordamos brevemente, foi que, para ler e manipular alguns contadores, você terá que ter privilégios de administrador. Achei que isso realmente só entrou em jogo quando se tratava de criar categorias de contador. Normalmente, para ler qualquer um dos valores que você não tenha encontrado em qualquer problema. Se você está tendo problemas para ler uma categoria ou um contador, certifique-se de que você escreveu tudo bem e a capitalização adequada. Os nomes podem ser um pouco complicados e garantir que tudo seja exato. Use o monitor de desempenho para ajudar a obter os nomes das categorias e os contadores corretos para que você não esteja batendo sua cabeça contra a parede com este. O último getcha, ao enumerar a lista de categorias e contadores, tenha cuidado. Algumas das listas podem ficar muito longas e demorar muito para listar. Estamos falando sobre algumas categorias listando milhares de linhas de dados estatísticos Se algo parece estar congelado por alguns segundos, seja paciente. Espero que você goste de trabalhar com os contadores de desempenho e que você possa usar essas informações no próximo projeto. Deixe-nos todos saber o que você usou contadores de desempenho em nossos comentários abaixo, então todos devemos aproveitar a glória do seu 8220leetness8221. Obrigado por ler Sobre o autor Martyr2 é o fundador do Codage Lexicon e autor dos novos ebooks The Programmers Idea Book e Diagnosticando o Problema. Ele é programador há mais de 18 anos. Ele trabalha para uma empresa de desenvolvimento de aplicativos quente em Vancouver, Canadá, que presta serviço a algumas das maiores telecomunicações do mundo. Ele ganhou inúmeros prêmios por sua orientação em desenvolvimento de software e contribui regularmente para várias comunidades em toda a web. Ele é um especialista em vários idiomas, incluindo PHP, CC, Java e muito mais. Posts relacionados Esta questão pode parecer um pouco estranha, mas estou tentando executar o VS2005 através de um processo e executar um comando específico e eu waitforexit (). Estou redirecionando minha entrada e saída com êxito, mas de vez em quando eu recebo uma janela WindowMessage Window Error Reporting. O problema é que eu estou remoting, então, quando esta janela de mensagem ocorrer durante a execução do processo, eu vou pendurar a menos que eu logar na outra máquina (remoting) e fechar a janela. Existe alguma maneira de matar programaticamente esta janela ou, possivelmente, desativar a janela do mensagem, eu pensei em executar o VS em uma execução silenciosa (ainda não consegui encontrar uma maneira de fazê-lo). Eu também tentei ver se há algo que está sendo lançado quando isso ocorre comparado ao quando não. Quinta-feira, 25 de outubro de 2007 8:32 PM Bem, eu tentei usar FindWindow e FindWindowEx junto com SendMessage, mas não consegui encontrar o identificador de janela correto. Mas, como eu sei que uma caixa de Msssage de relatórios de erros do Windows aparecerá, verifiquei se era seu próprio processo (e é). O processo é dwwin. exe (Dr. Watson Win) e tudo o que eu tinha que fazer era isso para me permitir corrigir o problema atual. Substitua o atual bloco de código abaixo para a declaração WaitForExit () que eu tinha anteriormente. Proc. WaitForExit (60000) Processo ProcArray Processo. GetProcessesByName (quotdwwinquot) foreach (Process ProcessFound no ProcArray) Procuram-me para verificar se você conseguiu obter o Process. MainWindowTitle (), mas está configurado para quotquot. Então, isso é um hack e eu realmente não gosto de usá-lo, mas funciona para a execução atual. Segunda-feira, 29 de outubro de 2007 7:26 PM Não, posso redirecionar entrada e saída sem problemas. O erro que recebo é o relatório geral de erros do Windows e, infelizmente, é em japonês, então não sei qual é o erro exato, mas é o erro geral. Eu não tenho o código na minha frente, mas eu configurei delegatesthreads para ler redirecionado o erro e a saída depois de sair do processo inteiro. Eu não posso inventar qualquer coisa e sou capaz de executar o mesmo processo em meu próprio computador, mas não sou capaz de fazer este um comando específico através da comunicação remota. Eu vou tentar amanhã remoting em uma máquina não-japonesa no trabalho e vou publicar minhas descobertas, independentemente. Sexta-feira, 26 de outubro de 2007 2:34 AM Você está executando o quotcmdquot do console. Se sim, você deve digitar sair também. Sexta-feira, 26 de outubro de 2007 4:50 Se você tiver uma idéia de quanto tempo seu processo vai levar, então você pode usar bool exitted process. WaitForExit (timeInMilliSeconds) se (saído) Processo caducidado antes do período de tempo limite. Else Mensagem de erro de impressão Isso pode não estar relacionado ao que você está fazendo, mas eu tive uma experiência em que o processo não iria sair se eu redirecionasse sua saída. Tente desabilitar o redirecionamento de saída e veja se o processo é encerrado. Experimente, pode funcionar. Sexta-feira, 26 de outubro de 2007 11:58 AM Gostaria de tentar isso, mas é muito um hack. Eu tenho muitos comandos diferentes que levam diferentes quantidades de tempo (30 segundos a 25 minutos), então não há configurações de tempo real que eu poderia colocar sem destruir o meu desempenho. Esta função tem funcionado corretamente para vários comandos nos últimos 6 meses e agora ele decide sair comigo. Eu tentei em um computador diferente sem problemas (o que realmente está me mexendo). Eu sei que não é o redirecionamento do outputerror porque uma nova WINDOW está sendo criada no servidor ao qual eu estou remoting. Assim que eu fechar essa janela, meu processo sai como esperado e a saída correta é exibida no lado do Usuário. Obrigado pela sua ajuda, mas estou ficando realmente frustrado com este problema. Sexta-feira, 26 de outubro de 2007 3:01 PM Sem saber o detalhe da mensagem, estava apenas adivinhando o problema. Você instalou o beta 3.5 beta ou o Visual Studio 2008 beta? Como você está usando Processo para iniciar o programa, Process. Start (quotfile. exequot), ou você está usando ProcessStartInfo sexta-feira, 26 de outubro de 2007 3:21 PM Não, eu tenho 2003 e 2005 instalados. Proc new Process () procSI novo ProcessStartInfo () Em seguida, configurei um novo tópico para o StandardError e StandardOutput I então escreva meus comandos e se (redirecionando o padrão para fora) Inicie o thread para st. Out Se (redirecionamento de erro padrão) Inicie thread para st. Erro Proc. WaitForExit () lt -------- é onde ocorre a janela Generic Windows Error Reporting. Eu traduzi o que pude da Janela que aparece. Microsoft Visual Studio 2005 Porque o problema ocorre, ele termina o Microsoft Visual Studio 2005. Aplicando inconvenientes, não há desculpa. Obrigado novamente por todo o seu tempo. Eu criei o sIn de StreamWriter antes de criar o objeto Process Process. Em seguida, redireciono a entrada após o comando proc. Start (), então, como eu não possuo isso, eu posso fazer a mudança para mover o sIn. Close () para depois da chamada WaitForExit para ver se isso faz alterações. O Proc era um tipo, deveria ter sido proc. Novamente, não é uma mensagem de erro, portanto, não há rastreamento de pilha. O redirecionamento do meu StandardError está vazio e o redirecionamento de saída padrão contém o que eu esperava, mas nada indicando que ocorreu um erro. É por isso que tudo ainda funciona depois que eu fechar a janela Windows Error Reporting. Eu publicarei o que acontece depois de eu mover a linha sIn. Close () abaixo da linha WaitForExit (). Sexta-feira, 26 de outubro de 2007 16:59 Peter Ritchie escreveu: Você não deseja fechar o objeto sIn até que o aplicativo tenha saído se você estiver redirecionando. Não se deve fechar nenhum desses fluxos. O objeto Process é dono deles e é o responsável pela limpeza depois de si. Um deve ao máximo chamar Process. Dispose () depois de concluído o objeto Processo. Você certamente não precisa (ou seja, é redundante), mas não deve causar um problema após o processo ter saído. Process. Close é o método recomendado para fechar os fluxos de entrada padrão e padrão (e padrão). Sexta-feira, 26 de outubro de 2007 5:03 PM Eu ficaria surpreso se o método Dispose não chamasse de Fechar, pelo menos como parte de sua operação. Eu preferiria usar o fato de que, desde que o Processo implementa IDisposable (indiretamente através do componente de extensão que o implementa), um deve invocar Dispose e permitir que a limpeza adequada. Eu não recomendaria invocar Process. Close em vez de, nem além de, Process. Dispose. Sim, descarte as chamadas Fechar. Minha primeira recomendação é usar um bloco de uso, o meu segundo é chamar Close quando você sabe quando você terminar com ele. Em objetos que implementam um método quotClosequot, apesar de serem IDisposable, é muito mais claro usar o método quotClosequot. Além disso, sem utilizar um bloco de uso, você não tem como escopo a variável e a chamada para Dispose - o objeto pode ser usado após a chamada para Dispose. Se você usa Close youve, descartou todos os seus recursos gerenciados, mas o objeto ainda pode ser usado (ou seja, ele não foi sinalizado como quotdisposedquot e você pode usá-lo para executar outro aplicativo sem alocar um novo objeto Process - o que, de outra forma, lançaria ObjectDisposedException ). Sexta-feira, 26 de outubro de 2007 6:09 PM Então, se a primeira recomendação é usar um bloco de uso, então o próximo melhor seria chamar Dispose. Não é Close, quando, como você disse, você sabe que você está feito com o objeto. Ao ligar apenas Close em algo que implementa IDisposable, o desenvolvedor está cometer um erro. Se Dispose faz alguma limpeza adicional além de apenas delegar para Fechar, então o programador está configurando-se para um bug, apenas ligando para Fechar. Pode haver um caso para chamar Close, mas somente se você não for feito com o objeto, como você indicou no final da sua última resposta. Mas quando terminar com isso, chame Dispose. Sexta-feira, 26 de outubro de 2007 6:20 PM Então, se a primeira recomendação é usar um bloco de uso, então o próximo melhor seria chamar Dispose. Não é Close, quando, como você disse, você sabe que você está feito com o objeto. Ao ligar apenas Close em algo que implementa IDisposable, o desenvolvedor está cometer um erro. Se Dispose faz alguma limpeza adicional além de apenas delegar para Fechar, então o programador está configurando-se para um bug, apenas ligando para Fechar. Pode haver um caso para chamar Close, mas somente se você não for feito com o objeto, como você indicou no final da sua última resposta. Mas quando terminar com isso, chame Dispose. Na verdade, é muito mais equivalente a: DisposableClass obj new DisposableClass () IDisposable descartable obj como IDisposable if (nulo descartable) Mas sim, isso é o que uma declaração de uso é quotfunctionally equivalentquot, mas eu não concordo chamando explicitamente Dispose na presença de um método quotClosequot deve Seja a primeira escolha por causa da falta de escopo com a chamada Dispose. Por exemplo, o seguinte: usando (processo processo processo novo ()) eu tive o serviço em execução, mas eu parei porque ele tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim, começando meu cliente. Eu não comentei a linha sIn. Close () agora e reiniciei o serviço e o Cliente e tudo está funcionando como antes. Posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de Relatório de Erros do Windows ainda (como era antes). Então, no meu caso, PRECISO fechar o fluxo de entrada para poder sair do processo conforme o esperado. Existem outras idéias que eu posso recomendar a linha sIn. Close () se você quiser verificar algo. Sexta-feira, 26 de outubro de 2007 7:19 PM Anthony Maimone escreveu: Eu tinha o serviço funcionando, mas eu parei porque tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim começando meu cliente . Eu não comentei a linha sIn. Close () agora e reiniciei o serviço e o Cliente e tudo está funcionando como antes. Posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de Relatório de Erros do Windows ainda (como era antes). Então, no meu caso, PRECISO fechar o fluxo de entrada para poder sair do processo conforme o esperado. Existem outras idéias que eu posso recomendar a linha sIn. Close () se você quiser verificar algo. Seria útil ver os detalhes da exceção quando você receber o erro (como a pilha de chamadas). Como você está usando a entrada padrão e a saída padrão Você está usando qualquer método ReadLine Peter, meu ponto é: Se você não convoca Dispose em um objeto que implementa (direta ou indiretamente) IDisposable, então você está apenas pedindo um bug. No entanto, não quero argumentar sobre isso sem parar. Você pode continuar a fazê-lo do jeito que você faz, e eu vou ficar com o meu. Enquanto não tivermos que manter o código de cada outro, tudo bem. E, a propósito, um bloco quotusingquot também não o protege. Nada impede que você declare a variável fora do bloco (se eu me lembro corretamente), então ainda pode estar no escopo após o fim do bloco. Você precisa ser diligente ao escrever o código correto. Se você declara isso na declaração quotusingquot, isso é uma maneira. Mas descartar o uso da abordagem experimental apenas porque deixa a variável no escopo não é realmente o ponto. Ainda precisa ser Dispose () d em algum lugar. Sexta-feira, 26 de outubro de 2007 7:34 PM Peter Ritchie escreveu: Anthony Maimone escreveu: Eu tinha o serviço funcionando, mas eu parei porque tinha funcionado por 2 horas e nunca tinha o ponto de parada que deveria ter atingido dentro de 10 minutos de Eu começando meu cliente. Eu não comentei a linha sIn. Close () agora e reiniciei o serviço e o Cliente e tudo está funcionando como antes. Posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de Relatório de Erros do Windows ainda (como era antes). Então, no meu caso, PRECISO fechar o fluxo de entrada para poder sair do processo conforme o esperado. Existem outras idéias que eu posso recomendar a linha sIn. Close () se você quiser verificar algo. Seria útil ver os detalhes da exceção quando você receber o erro (como a pilha de chamadas). Como você está usando a entrada padrão e a saída padrão Você está usando algum método ReadLine Novamente, isso NÃO é uma Exceção que está sendo jogada, então eu não estou vendo detalhes de exceção. Eu não vou diretamente para o bloco catch no meu código, eu retomo DIRECTAMENTE após a chamada WaitForExit (). A janela que estou recebendo é a mesma que você obtém quando algum produto da Microsoft fecha inesperadamente e MS quer informações sobre o Crash. Então, novamente, não há detalhes de exceção. No entanto, em um dos logs do sistema, estou recebendo uma mensagem (traduzida do japonês) quotDevenv. exe erros de aplicativo ocorrem, 8.0.50727.762 versão dos erros ocorridos módulo msvcr80.dll, versão 8.0.50727.762, erro ocorreu endereço 0x00039001. Para obter mais informações, go. microsoftfwlinkevents. asp o Helo e o Centro de suporte, por favor, consulte. quot Estou redirecionando a entrada padrão para passar nos diferentes comandos porque eu estava tendo problemas para fazê-los funcionar como eu queria formar o StartInfo. Estou redirecionando os fluxos de Saída e Erro para verificar o que eles têm neles depois que o processo foi encerrado. Isso me permitirá verificar qualquer coisa que eu gostaria em qualquer fluxo, uma vez que terminamos. Eu também não permito que nenhum dos segmentos de saída ou redirecionamento de erro se junte até que o processo tenha passado a chamada WaitForExit. Estou completamente perplexo. Sexta-feira, 26 de outubro de 2007 7:53 PM Peter, meu ponto é: Se você não convoca Dispose em um objeto que implementa (direta ou indiretamente) IDisposable, então você está apenas pedindo um bug. No entanto, não quero argumentar sobre isso sem parar. Você pode continuar a fazê-lo do jeito que você faz, e eu vou ficar com o meu. Enquanto não tivermos que manter o código de cada outro, tudo bem. Eu não concordo. Não é um quotbugquot para não chamar Dispose. Seus recursos não serão liberados imediatamente, mas o GC os liberará se precisar da memória (assumindo que o padrão Dispose está corretamente implementado e existe um finalizador). Se a classe que você estiver usando implementa um método quotClosequot que não faz todas as mesmas coisas que quotDisposequot, Close deve ser documentado como tal ou há um bug na classe. Nunca encontrei uma classe de estrutura que implemente IDisposable e um método Close () que introduziu um quotleakquot quando Close foi chamado sem chamar Dispose. O padrão esmagador para DisposeClose é que Dispose calls Close, além de definir um quotdisposedquot flag (usado para jogar ObjectDisposedException). Na verdade, isso é detalhado na Referência Geral do Framework: quotOccasionalmente, um nome específico do domínio é mais apropriado que o Dispose. Por exemplo, um encapsulamento de arquivo pode querer usar o nome do método Fechar. Nesse caso, implemente Dispose em particular e crie um método Public Close que chame Dispose. O exemplo de código a seguir ilustra este padrão. Você pode substituir Close com um nome de método apropriado para o seu domínio. quot de Implementar finalizar e descartar para limpar recursos não gerenciados, bem como quotPara determinadas classes de objetos, como arquivos ou objetos de conexão de banco de dados, um método Close melhor representa a operação lógica que Deve ser executado quando o consumidor de objetos terminar com o objeto. quot de Melhorar o desempenho do código gerenciado (embora também também detalhe quotIn casos bem escritos, ambos são funcionalmente equivalentes. Isso implica que usar o Close é mais claro com quotbetter representaquot.) E, a propósito, um bloco quotusingquot também não o protege. Nada impede que você declare a variável fora do bloco (se eu me lembro corretamente), então ainda pode estar no escopo após o fim do bloco. Você precisa ser diligente ao escrever o código correto. Se você declara isso na declaração quotusingquot, isso é uma maneira. Mas descartar o uso da abordagem experimental apenas porque deixa a variável no escopo não é realmente o ponto. Ainda precisa ser Dispose () d em algum lugar. Sim, há todos os tipos de maneiras em que você pode se atirar no pé, mas esse não é um cenário que discutimos. Eu pessoalmente abateria qualquer código que eu analisei assim. Isso seria na minha lista não recomendada. Sexta-feira, 26 de outubro de 2007 7:54 PM Novamente, esta NÃO é uma Exceção que está sendo jogada, então eu não estou vendo detalhes de exceção. Eu não vou diretamente para o bloco catch no meu código, eu retomo DIRECTAMENTE após a chamada WaitForExit (). A janela que estou recebendo é a mesma que você obtém quando algum produto da Microsoft fecha inesperadamente e MS quer informações sobre o Crash. Então, novamente, não há detalhes de exceção. No entanto, em um dos logs do sistema, estou recebendo uma mensagem (traduzida do japonês) quotDevenv. exe erros de aplicativo ocorrem, 8.0.50727.762 versão dos erros ocorridos módulo msvcr80.dll, versão 8.0.50727.762, erro ocorreu endereço 0x00039001. Para obter mais informações, go. microsoftfwlinkevents. asp o Helo e o Centro de suporte, por favor, consulte. quot Eu assumi que seu aplicativo estava gerando a mensagem (nesse caso, você sempre deveria obter uma exceção e um rastreamento de pilha), não era claro que você retomasse após a chamada Para WaitForExit (). Parece-me que a aplicação que você está executando está terminando anormalmente. Você está executando devenv. exe? Eu não tenho certeza do que você pode fazer em seu aplicativo para impedir que outro aplicativo termine de forma anormal. Anthony Maimone escreveu: Estou redirecionando a entrada padrão para passar nos diferentes comandos porque eu estava tendo problemas para fazê-los funcionar como eu queria formar o StartInfo. Estou redirecionando os fluxos de Saída e Erro para verificar o que eles têm neles depois que o processo foi encerrado. Isso me permitirá verificar qualquer coisa que eu gostaria em qualquer fluxo, uma vez que terminamos. Eu também não permito que nenhum dos segmentos de saída ou redirecionamento de erro se junte até que o processo tenha passado a chamada WaitForExit. Estou completamente perplexo. Você pode obter um impasse se você bloquear a leitura e a saída padrão dos aplicativos - o que seria desbloquear se você fechou o fluxo, eu acredito. A única coisa em que posso pensar é criar um aplicativo que está sendo executado no servidor e monitorar o Windows que vem formando os processos que você está controlando remotamente e depois encontrar os botões corretos e pressioná-los, programaticamente, pressionando uma mensagem para a bomba de mensagem da janela de diálogo . Este alos acontece com excel, word e outras aplicações que podem ser usadas com autimation O MSFT não criou esses aplicativos para serem executados sem a interação do usuário, então, de vez em quando, você obterá o Windows em erros. Você considerou usar o MSBuid que é mais apropriado para compilações de lote, também parece que nos servidores de compilação TFS 2008 será fácil de construir. Sábado, 27 de outubro de 2007 11:07 AM Bem, eu tentei usar FindWindow e FindWindowEx junto com SendMessage, mas não consegui encontrar o identificador de janela correto. Mas, como eu sei que uma caixa de Msssage de relatórios de erros do Windows aparecerá, verifiquei se era seu próprio processo (e é). O processo é dwwin. exe (Dr. Watson Win) e tudo o que eu tinha que fazer era isso para me permitir corrigir o problema atual. Substitua o atual bloco de código abaixo para a declaração WaitForExit () que eu tinha anteriormente. Proc. WaitForExit (60000) Processo ProcArray Processo. GetProcessesByName (quotdwwinquot) foreach (Process ProcessFound no ProcArray) Procuram-me para verificar se você conseguiu obter o Process. MainWindowTitle (), mas está configurado para quotquot. Então, isso é um hack e eu realmente não gosto de usá-lo, mas funciona para a execução atual. Segunda-feira, 29 de outubro de 2007 7:26 PM

No comments:

Post a Comment