Skip to main content

Omnithreadlibrary Waitforexit


A maior parte do tempo trabalhando como desenvolvedor nos dá a liberdade de mexer no nosso mundo de alto nível de abstração, mas às vezes a realidade chuta em partes privadas e diz para você encontrar um homem que realmente entende. Acabei de ter uma dessas experiências. Eu acho que basta listar os dados do canto como uma lista de itens para que você entenda o que temos aqui: Win2008 Server 64Bit Environment Aplicativo WPF usado por múltiplos clientes simultaneamente O aplicativo é um iniciador, que abre outros aplicativos usando Process. Start () Ocasionalmente nós Obtenha a exceção listada abaixo EDIT 1 Após alguma inspeção, ela possui mais detalhes: o lançamento é um Processo em 2 Passos, o Lançador lança uma janela intermediária usando Process. WaitForExit () Na janela intermediária, outros processos podem ser iniciados da mesma maneira (Process. WaitForExit). Com apenas a janela intermediária aberta e nenhuma interação do usuário, o processo de lança o número de alças aumenta ao longo do tempo. O aumento máximo observado aqui é 400 - 6000 alças. Os fatos adicionados no Editar realmente me fazem pensar se pode haver vazamento de identificador na estrutura em algum lugar. Estou tentando isolar o problema e verificar se posso reproduzi-lo do zero. Entretanto, qualquer tipo de sugestão, ideia, suporte ou até mesmo chocolate é aceita com prazer EDIT 2. Na tentativa de tornar o processo responsivo ao PostMessage (). Removemos Thread. WaitForExit. Em vez disso, adicionamos um manipulador para o evento Processs Exited e enviamos o Iniciador para um loop como o seguinte: O Exited-Handler define foo como falso e não faz mais nada. Ainda assim, o número de Handles sobe (400 a 800 em meia hora). EDIT 3 Aqui vem algo interessante, finalmente. Isso o mantém como é suposto ser, poucas alças, todos astutos. Agora, isso me faz pensar o que está errado aqui. Vou falar com o desenvolvedor responsável novamente para verificar o que mais o iniciador faz. Até agora, eu ouvi dizer que ele lê alguns valores de configuração usando XmlDocument. Load (). O que não é um IDisposable - faz com que seja difícil produzir qualquer vazamento aqui. Perguntei 10 de abril 12 em 10: 25Processos de módulos com o OmniThreadLibrary A unidade OtlParallel na OmniThreadLibrary oferece algumas soluções de alto nível que permitem que você execute facilmente alguns tipos de processos em paralelo. Até agora, suportou cálculos de fundo autônomos (Parallel. future), processos paralelos independentes (Parallel. Join) e cálculos de loop onde a tarefa em segundo plano é sem estado (ou seja, depende apenas da entrada 8211 do valor de loop 8211 e não de cálculos Feito em outras entradas 8211 valores de loop Parallel. ForEach). Mas muitos processos de tempo não se enquadram em nenhuma dessas categorias. Mason Wheeler recentemente sugeriu adicionar suporte para processos de vários estágios. Durante o fim de semana I8217ve implementado na OmniThreadLibrary e agora este recurso está pronto para você começar a testar. Agradecemos a Mason por sua sugestão e também por trabalhar na implementação e design do novo Parallel. Pipeline. O pressuposto é que o processo pode ser dividido em etapas (ou suprocessos), conectados com filas de dados. Os fluxos de dados da fila de entrada (opcional) para o primeiro estágio, onde é parcialmente processado e depois emitido na fila intermediária. O primeiro estágio continua a ser executado, processa mais dados de entrada e produz mais dados de saída. Isso continua até a entrada completa ser processada. A fila intermediária leva ao próximo estágio que faz o processamento de forma semelhante e assim por diante. No final, os dados são enviados para uma fila que pode ser lida e processada pelo programa que criou esse processo de vários estágios. Como um todo, um processo de vários estágios funciona como um pipeline. Os dados 8211 entram, os dados saiem (e um milagre ocorre no meio). O que é importante aqui é que nenhum estágio compartilha o estado com qualquer outro estágio. A única interação entre etapas é feita com os dados passados ​​através das filas intermediárias. A quantidade de dados, no entanto, não precisa ser constante. É perfeitamente possível que um estágio gere mais ou menos dados do que recebeu na entrada. Em um programa clássico de um único segmento, o plano de execução de um processo em vários estágios é muito simples. Em um ambiente multithread, no entanto, podemos fazer melhor do que isso. Como os estágios são amplamente independentes, eles podem ser executados em paralelo. Configurar tarefas e filas intermediárias é um processo relativamente simples 8211, mas longe do processo trivial 8211. Por conseguinte, seria melhor se pudesse ser automatizado de alguma forma. Essa foi a idéia geral que o Mason veio comigo e juntos criamos uma nova parte do OmniThreadLibrary 8211 Parallel. Pipeline. Parallel. Pipeline Um pipeline é criado chamando a função Parallel. Pipeline que retorna a interface IOmniPipeline. Existem duas versões sobrecarregadas 8211 para construção geral de pipeline e outra para tubulações simples que não requerem nenhuma configuração especial. A última versão leva dois parâmetros 8211 uma matriz de estágios de processamento e uma fila de entrada opcional. A fila de entrada pode ser usada para fornecer dados iniciais para a primeira etapa. Também é completamente válido passar 8216nil8217 para o parâmetro da fila de entrada e executar o primeiro estágio sem qualquer entrada. As coleções de bloqueio são usadas para filas de dados na implementação Parallel. Pipeline. As etapas são implementadas como procedimentos anônimos, procedimentos ou métodos que tomam dois parâmetros de fila 8211 um para entrada e outro para saída. Exceto na primeira etapa em que a fila de entrada pode não ser definida, ambas são criadas automaticamente pela implementação do Pipeline e passadas para o delegado do estágio. O próximo fragmento de código mostra a função Pipeline simples em ação. É tirado do teste OmniThreadLibrary 41Pipeline. Parallel. Pipeline aceita uma série de delegados de fase e retorna a interface do IOmniPipeline. Run é então chamado na interface para configurar a infra-estrutura, iniciar todas as tarefas e retornar a fila de saída. O programa principal aguarda a última etapa para produzir um resultado e porque sabe que haverá exatamente um valor produzido, pode aguardá-lo chamando a função Next (que também foi implementada recentemente e é apenas um invólucro simples em torno da função Take) . O poder total da interface IOmniPipeline geralmente é acessado através da função Parallel. Pipeline sem parâmetros. A entrada define a fila de entrada. Se não for chamado, a fila de entrada não será atribuída e a primeira etapa receberá nil para o parâmetro de entrada. O estágio adiciona um estágio de pipeline. Etapas adiciona vários estágios de pipeline. NumTasks define o número de tarefas de execução paralela para o estágio (s) que acabou de ser adicionado com a função Stage (s) (IOW, call Stage seguido de NumTasks para fazer isso). Se for chamado antes de qualquer etapa ser adicionada, ele especificará o padrão para todas as etapas. O número de tarefas de execução paralelas para um estágio específico ainda pode ser substituído ao chamar NumTasks após o chamado do Stage. Leia mais sobre a execução paralela na seção Etapas paralelas abaixo. O Throttle define os parâmetros de aceleração para o (s) estágio (s) apenas adicionados com a função Stage (s). Assim como o NumTask afeta os padrões globais ou os estágios atualmente adicionados. Por padrão, a aceleração está configurada para 10240 elementos. Consulte a seção Throttling abaixo para obter mais informações. Run faz todo o trabalho árduo 8211 cria filas e configura tarefas do OmniThreadLibrary. Ele retorna a fila de saída que pode ser usada em seu programa para receber o resultado da computação. Mesmo que a última etapa não produza nenhum resultado, esta fila pode ser usada para sinalizar o fim da computação. Quando cada etapa termina, CompleteAdding é chamado automaticamente na fila de saída. Isso permite que o próximo estágio detecte o final da entrada (o cobrador de bloqueio do enumerador irá sair ou o TryTake retornará falso). O mesmo acontece com a fila de saída. Um exemplo (também tirado do 41Pipeline) ajudará a explicar tudo isso. Primeiro, um parâmetro de aceleração global é definido. Será aplicado a todas as etapas. São então adicionados dois estágios, cada um com uma chamada separada para a função Stage. Outros dois estágios são então adicionados com uma chamada. Ambos são definidos para serem executados em duas tarefas paralelas. Ao final, é adicionada outra etapa e toda a configuração é executada. O processo completo usará sete tarefas (uma para StageGenerate. Uma para StageMult2. Duas para StageMinus3. Duas para StageMod5 e uma para StageSum). Geradores, Mutadores e resumos Let8217s examinam três exemplos diferentes de estágios de multiprocessamento antes de dar uma volta para as águas profundas. O primeiro exemplo é um exemplo de uma primeira etapa que aceita nenhuma entrada e apenas gera saída que é passada para o próximo estágio na cadeia. (Todos os exemplos são novamente retirados do 41Pipeline.) O segundo exemplo lê os dados da entrada e para cada entrada gera e transmite um valor de saída. O último exemplo lê dados da entrada, adiciona todos os valores juntos e produz apenas um valor de resumo. Todos os exemplos são apenas casos especiais do princípio geral 8211, não há correlação entre a quantidade de dados de entrada e a quantidade de dados de saída. There8217s também absolutamente nenhuma exigência de que os dados devem ser todos os números. Sinta-se livre para transmitir qualquer coisa que possa ser contida em TOmniValue. Throttling No meu caso de teste (41Pipeline), uma grande quantidade de dados (um milhão de números) é passada através do processo em vários estágios. Se um segmento for suspenso por algum tempo 8211 ou se ele for executado um cálculo que seja mais lento do que o fio anterior 8211, essa fila de entrada thread8217s pode preencher dados que podem causar grande quantidade de memória para serem alocados e posteriormente liberados. Até mesmo o fluxo de dados, o Pipeline usa a aceleração. Uma nova funcionalidade na coleção de bloqueio. Throttling define o tamanho máximo (em unidades TOmniValue) da coleção de bloqueio. Quando a quantidade especificada de itens de dados é armazenada na coleção, não podem ser adicionados mais dados. A função Adicionar simplesmente bloqueará até que a coleção esteja vazia o suficiente ou CompleteAdding tenha sido chamado. A coleção é considerada vazia o suficiente quando a contagem de dados cai abaixo de algum valor que pode ser passado como um segundo parâmetro para a função Throttle ou é calculado como um 34 do limite de tamanho máximo se o segundo parâmetro não for fornecido. Etapas paralelas Geralmente, uma tarefa é iniciada para cada etapa da tubulação. Em alguns casos especializados, no entanto, pode ser desejável executar mais de uma tarefa paralela para cada etapa. Um exemplo disso foi dado no método btnExtended2Click, acima. O pipeline gerado neste exemplo pode ser representado com o seguinte diagrama. Como você pode ver, there8217s sempre é apenas uma fila sentada entre os estágios, mesmo que existam várias unidades de processamento para um palco. Isso é facilmente realizado pelo IOmniBlockingCollection, que oferece suporte a vários leitores e vários escritores de uma maneira que é de qualidade. No entanto, há uma advertência importante. Se você dividir um estágio em várias tarefas, os dados serão processados ​​em uma ordem indeterminada. Você não sabe quantos itens serão processados ​​por cada tarefa e em qual ordem serão processados. Pior ainda, os dados 8211 sairão do estágio multitask em uma ordem indeterminada (a saída de dados de uma tarefa será entrelaçada com os dados da outra tarefa). A partir desse momento, nenhuma maneira de impor o pedido original, pois isso é feito na implementação Parallel. ForEach. Concluído ou não Embora o Parallel. Pipeline tenha sido cometido e esteja pronto para testar, eles ainda podem ter algumas peculiaridades no código. I8217ll segue isso com um post ou dois em testes e desempenho e você pode querer esperar até então antes de começar a usá-lo. Se você quiser me ajudar com o desenvolvimento, então vá em frente, use-o e relate todos os problemas de volta, aqui nos comentários ou no fórum.

Comments

Popular posts from this blog

Deslocamento Em Movimento Média Youtube

ANÁLISE TÉCNICA A média móvel deslocada ou a redução do ruído na negociação intradiária EURUSD A chave para a análise técnica é uma leitura fria e disciplinada dos dados dos preços, a direção do sentimento que isso destaca e a interpretação desses dados em futuros e futuros movimentos prováveis . Isso parece fácil, mas um elemento-chave é a pureza dos dados ou, se thatrsquos não é possível (e raramente é), uma remoção do ruído que envolve o movimento dos preços e o efeito resultante sobre os indicadores técnicos. Isto é especialmente válido quando se trata de negociação intradiária quando cada pip pode ter um valor significativo. Por lsquonoisersquo, eu não entendo gritos de comerciantes, corretores e vendedores que costumavam distrair os analistas técnicos em todas as salas de negócios, mas o ruído criado por voláteis movimentos do mercado - Pare as perdas desencadeadas, reações de eventos, anúncios de figuras econômicas e declarações de analistas de mídia. Um dos métodos mais simples...