Timer - C# - Portugal-a-Programar
By soulbe, March 25, 2010 in C#
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"]))
//ad 2: set interval to remaining millis to update time
timer.Interval = frequency;
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?
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)
Eu percebi. Queria era saber mesmo os valores nas duas situações que reportaste.
1ª situação = 3600000
2ª situação = 39600000
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.
Afinal só mesmo amanhã, outros problemas para resolver
[A processar, daqui a 1h já dou feedback ]
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
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