Plunging into .NET Development

Weblog Pieter Gheysens
Microsoft .NET Development - C# - Enterprise Library - Visual Studio 2005 Team System - Compuware DevPartner - ...
 


Thursday, August 31

Elapsed event of Timer not raised

This bug caused us a lot of trouble.
In the event handler for the Elapsed event of the Timer object, if you call the Stop method of the Timer object, the reference to the Timer object is lost. The garbage collector then reclaims the memory that is associated with the Timer object. Later, even if you call the Start method of the Timer object to raise the Elapsed event, the call does not work. The Elapsed event is not raised. Typically, this problem occurs if the computer that is running the application is under a heavy load or if many timer objects are running.
That was exactly what was happening in our code. We stopped the timer at the start of the Elapsed event to prevent Timer Event Reentrance. In the finally block we re-started our timer again ...

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

{

   try

   {

      //stop timer

      timer.Stop();

 

      //Logic here ...

   }

   catch (Exception ex)

   {   }

   finally

   {

      //restart timer

      this.timer.Start();

   }

}


At irregular points of time one (or more) of our Timers (System.Timers.Timer) stopped firing their Elapsed event in the production environment. First we extended our logging to see what was exactly causing this problem and we were hoping that we would remark some exceptions/warnings in our logfiles. But, as you guessed : no sign of meaningful logging. Furthermore we could not reproduce this behaviour in our other environments (Developent - Testing - Quality). We were also questioning if we were using the correct Timer class (see a previous post and this post from Gabriel Lozano-Morán)?

Finally I bumped into the Knowledge Base Article that gave me the answer. A hotfix is made available by Microsoft [Prerequisite : .NET Framework 1.1 SP1 - determine Framework version]. These things are damn hard to debug/test! I hope this helps if you're in a similar situation.

1 Comments:

  • At 2:22 AM, Anonymous Gabriel Lozano-Morán said…

    Hello Pieter, a quickfix (read hack) could be to use GC.KeepAlive on the timer to make sure that the GC doesn't collect it yet.

     

Post a Comment

Links to this post:

Create a Link

<< Home