1

Possible Duplicate:
System.Timer elapsed event seems to fire late for short intervals in .Net

I use System.Timers.Timer in my windows service. Interval set to 60000 ms, but every next elapse, timer interval increases on some ms..Here example of log:

2011-09-05 00:00:37,177 [80] INFO - 
timer_Elapsed;

2011-09-05 00:01:37,187 [8] INFO  - 
timer_Elapsed;

2011-09-05 01:24:38,279 [71] INFO   - 
timer_Elapsed;

But I need to elapse timer in 37 seconds, as example, but after work some time, we have elapse timer in 38, 39, 40 .. sec..

I don't need very precision timer, but i need to elapse 37 +- 1sec every time..

How i can resolve this problem???


I one time set Interval property in:

protected override void OnStart(string[] args)
{
   log4net.Config.XmlConfigurator.Configure();
   EmailReminderService.Logger.Info("Service started");

   _timer.Interval =Convert.ToInt32(ConfigurationManager.AppSettings["Interval"]);
   _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
   _timer.Enabled = true;               
}

private void timer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
{
   EmailReminderService.Logger.Info("timer_Elapsed;");
   EmailReminderManager manager = new EmailReminderManager();
   manager.EmailReminderProcessing();
}

In timer elapsed method not use _timer object..

jww
  • 97,681
  • 90
  • 411
  • 885
Alexey Z.
  • 189
  • 1
  • 3
  • 14
  • 4
    http://stackoverflow.com/questions/5265259/system-timer-elapsed-event-seems-to-fire-late-for-short-intervals-in-net – Davide Piras Sep 07 '11 at 14:24
  • @Davide Piras: that's about really short intervals like 100 ms, while OP is talking about minutes. – CodeCaster Sep 07 '11 at 14:44
  • Could you post the relevant parts of your `timer_Elapsed` method and all other relevant changes to the _timer variable or members? Do you maybe simply lock your CPU so the delegate may be delayed as result? – eFloh Sep 07 '11 at 15:12
  • You may be experiencing the [Microsoft Minute](http://www.userfriendly.org/cartoons/archives/99mar/19990318.html). – jww Apr 30 '18 at 00:46

2 Answers2

0

we have elapse timer in 38, 39, 40 .. sec..

Are you sure you aren't doing something with the Interval property of your timer? It may vary since you aren't working on a Real-time OS, but a second being added every call sounds more like a bug on your side than in the Timer.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • Indeed sounds like a bug. Log the `_timer.Interval` value on `_timer.Elapsed` and see that it is as expected. – erikH Sep 07 '11 at 14:42
  • every time add something like 100 miliseconds, and i don't change interval property – Alexey Z. Sep 07 '11 at 14:58
0

On each iteration calculate how the time difference between now and the point in time where you want to trigger the next timer. Then set your interval to that value. This will prevent a drift.

//Once
DateTime start=DateTime.UtcNow;// Or if you prefer that the event
                               // happens on the same second no matter when
                               // the program started you can simply
                               // use a constant here

//At the end of the timer handler
int interval=(int)((DateTime.UtcNow-start).TotalSeconds*1000);
const int targetInterval=60000;
interval(interval+targetInterval/2)%targetInterval+targetInterval/2;
timer.Interval=interval;

This chooses an interval between 30 and 90 seconds so that you will hit the target time exactly.

The program deals gracefully with UtcNow<start since that may happen when the user changes the system clock.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • I think about it, if doesn't work anything..But i don't know that increase of timer interval is bug of System.Timers.Timer or maybe i do something wrong... – Alexey Z. Sep 07 '11 at 15:40
  • The system timer simply doesn't guarantee as much as you think it does. It doesn't care about drift or hitting the target exactly. For example if another thread with higher priority (or your own thread) is busy when the event occurs it will simply be delayed. Or if you use a timer with small intervals it will be much slower than one might naively expect(when not using `TimeBeginInterval` the effective interval is only accurate to about 16ms on a typical system). – CodesInChaos Sep 07 '11 at 15:52