tags:

views:

165

answers:

3

Is there a .NET Timer available in C# that can ensure there is no "drift" in between events? That is, if you set the timer to go off every X seconds, that after days of operating it won't drift, i.e. to ensure that approach number of X seconds events in a day remains in synch with what it should be?

If not, is there a well known code example that would wrap a Timer function in C# to do this?

+4  A: 

I'm assuming you have tried something already, and that it drifts.

If you want something to fire at say every 5 seconds from the hour (5,10,15,20..), you could set your timer to fire once, then in your callback, reset the timer to fire at DateTime.Now + number of seconds to the next 5 second interval.

This would prevent any drifting as long as your clock is correct.

Something like this

System.Timers.Timer timer = new Timer();

void Init()
{
    timer.Elapsed += timer_Elapsed;
    int wait = 5 - (DateTime.Now.Second % 5);
    timer.Interval = wait*1000;
    timer.Start();
}


void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    timer.Stop();
    int wait = DateTime.Now.Second % 5;
    timer.Interval = wait * 1000;
    timer.Start();
}
Mikael Svenson
sounds good - I guess I was wondering if there wasn't already a function that would do this already buried in the .NET framework somewhere
Greg
+5  A: 

sorry for only giving you a link to quartz.net, but this is a fully qualified, enterprise, tested, ... library ... you don't need to reinvent the wheel :)

if you worry about overhead, what is your definition for overhead? is it the file-size (binaries are about 0,5mb) or the overhead in the logic. well for the logic-part: i think that implementing their IJob-interface does a good job to force better code of the consumer. i'm not that big friend of inline-methods (just as an example, as you might fire their pointers on timer elapse) - classes would give you much more possibilities, and once again, force better oop, domain-design, ...

but: doing Console.WriteLine(...) with quartz.net would be overkill ... :)

Andreas Niedermair
Greg
see my edit!...
Andreas Niedermair
+1 Didn't know about this library, but I will certainly keep it in mind.
Mikael Svenson
A: 

As per Mikael, or even better, if there is a deterministic way to calculate ALL exact times of the event firing (e.g. StartDate + NumberEvents * Interval), then set the 'next' interval to be the difference between DateTime.Now and this calculated DateTime, to prevent cumulative rounding. Again, assuming that your clock is correct - use NTP or similar to keep in synch.

nonnb