Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

soulbe

Timer

Mensagens Recomendadas

soulbe

Boas.

Tenho um timer, cujo código coloco à frente, que quando o intervalo que lá coloco expira, irá sinalizar uma flag que fará que as threads que tenho a processar dados em concorrência parem o seu trabalho e esperam que seja feito o reset da flag.

O meu problema é que, imaginando que inicio o processamento as 16h e as 17 expira o intervalo, tudo corre na perfeição, mas se só expirar as 03h da manhã, nunca é executado! (as horas indicadas foram os intervalos testados). O que parece é que o timer foi desactivado ou limpo pelo GC.

Este comportamento já vos aconteceu? Até coloquei GC.KeepAlive(timer), para prevenir que o GC limpasse o timer, apesar de em príncipio ele estar activo numa thread do ThreadPool . Não me faz sentido nenhum é funcionar quando testo com um intervalo pequeno e não funcionar no outro caso.

private void StartTimer(ElapsedEventHandler handler, DateTime updateTime)
        {
            int frequency = GetFrequency(updateTime);
         
            if (frequency <= Convert.ToInt32(ConfigurationManager.AppSettings["SECURITYINTERVAL"]))
            {
                _signaled = true;
            }

            timer = new Timer();
            timer.Elapsed += handler;
            //ad 2: set interval to remaining millis to update time
            timer.Interval = frequency;
            //ad 3: enabling the timer
            timer.Enabled = true;
            timer.AutoReset = true;
            GC.KeepAlive(timer);
        }

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mjamado

Qual é o valor de frequency nos dois casos? Chuta aí para a consola...

E essa variável timer, é de classe, certo? E a classe está sempre activa?


"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
soulbe

O valor da frequencia é o valor da diferença entre o tempo actual e a hora que tenho de efectuar a sinalização, em milisegundos. Estou a escrever no log, só nao pus aqui essas linhas, para nao encher.

A variável Timer é uma variável estática da classe. A classe terá um método que tem o processamento multithreading que vai esperar pela sinalização da flag, por isso estará sempre activa. Termina o processamento,  espera x segundos, faz chamada recursiva, e anda nisto o dia todo até o timer expirar (queria eu)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mjamado

O valor da frequencia é o valor da diferença entre o tempo actual e a hora que tenho de efectuar a sinalização, em milisegundos. Estou a escrever no log, só nao pus aqui essas linhas, para nao encher.

Eu percebi. Queria era saber mesmo os valores nas duas situações que reportaste.


"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mjamado
Termina o processamento,  espera x segundos, faz chamada recursiva, e anda nisto o dia todo até o timer expirar (queria eu)

Hmmmm... limite de instanciação atingido?

Quando fazes uma chamada recursiva, o método anterior ainda está em memória e fica à espera de resposta. Como podes imaginar, ao fim de umas poucas de chamadas, tens uma call stack enorme, e não sei até que ponto o gajo se aguenta à bomboca.

Faz isso com eventos e callbacks e vê se resolve.


"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
DVD

Isso cheira-me a problemas de sincronização do lado das threads, e um possível deadlock, que mecanismo é que estás a usar para garantir a exclusão aquando a leitura da variavel?

Porque não um auto reset event para resolver esse problema? Resolvias esses loops desnecessários

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
soulbe

DVD, já é usado o autoResetEvent para esperar que as threads terminem o seu trabalho e sinalizar de volta. É usado um Semaphore FIFO para controlar os acessos ao counter que contem o numero de threads activas.

Mas sim, os loops que estava a fazer já foram retirados, eram desnecessários. A unica coisa que o handler que é passado ao timeout faz é sinalizar uma flag, e estando a flag sinalizada as workerThreads são paradas.

Ainda não tive tempo de voltar a testar isto, mas quando voltar à questão volto cá dar algum feedback

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.