Pergunta

I têm uma classe que contém um segmento de trabalho que recebe dados de uma fila em um ciclo.

Outra parte do aplicativo afunda um evento a partir desta classe, que os aumentos de classe para cada item da fila.

Estes eventos são disparados de forma assíncrona, para que nos horários de pico a outra parte do aplicativo pode ser o processamento de vários eventos ao mesmo tempo.

Isso deve ser bom, mas nós descobrimos um cenário onde isso pode causar problemas.

Precisamos de uma solução rápida, enquanto a principal questão fica resolvida. Será que o quadro fornecem uma maneira simples que posso forçar o segmento de trabalho para esperar enquanto cada evento é processado (assim eles são processados ??sequencialmente)? Se não, qual é a maneira mais fácil de implementar isso?

Foi útil?

Solução

Uma resposta simples seria lock () em um único objeto no manipulador de eventos. Todos os theads iria esperar para obter o bloqueio.

Outras dicas

A classe ManualResetEvent pode ajudá-lo aqui, a menos que eu não estou entendendo sua pergunta. Você pode usá-lo para bloquear o disparo do próximo evento até a última concluída.

Meu palpite é que você quer simplesmente ir longe de desencadear a ação, aumentando um evento e chamar o método diretamente.

eventos AFAIK vão ser assíncrono e eu não tenho conhecimento de alguma maneira "fácil" de mudar isso.

Acontece que há outra resposta. Você pode simplesmente adicionar o seguinte atributo para o método.

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]

Não há nenhuma maneira geral.

No final, os manipuladores precisa fornecer um mecanismo para o acompanhamento.

Se você estiver usando BeginInvoke, em vez de elevar os eventos diretamente, você pode usar um invólucro, dentro do qual você chamar o manipulador de eventos reais de forma síncrona, em seguida, levantar o invólucro de forma assíncrona. O invólucro pode manter um contador (com operações bloqueadas) ou definir um evento tão atenda às suas necessidades.

Algo como:

TheDelegate realHandler = theEvent;
var outer = this;
ThreadPool.QuereUserWorkItem(x => {
  // Set start of handler
  realHandler(outer, eventArgs);
  // Set handler finished
};

Todos os manipuladores de eventos afundando eventos gerados pelo segmento de trabalho-fila de leitura são chamados no segmento de trabalho-fila lendo. Enquanto os manipuladores de eventos não são de desova tópicos de seu próprio país, você deve ser capaz de esperar para os manipuladores de eventos ao fim chamando Thread.Join () na thread de trabalho-fila de leitura.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top