Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
soulbe

Timer

Recommended Posts

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);
        }

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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)

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other sites
soulbe

Afinal só mesmo amanhã, outros problemas para resolver ;)

[A processar, daqui a 1h já dou feedback  :P ]

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.