Reputation: 13
I want to write a program which needs to get a tick event each second. The program runs many hours and the tick must be in line with the seconds of the system clock. To use any kind of timer which fires an event each second is no good idea. There are to many inaccuracies. If you have an inaccuracy of 100ms per second, the timer is 6 minus behind the system clock each hour. But, it must be exact in line with the system clock.
To get an event from the system clock is ok.
To have inaccuracies is ok for single seconds but not over all.
What is your suggestion to solve this?
The solution must work on c# net6 (I plan to run the program on Windows and Linux).
Thanks
Upvotes: 0
Views: 1720
Reputation: 273844
This gets you to within 0..20ms after each whole second of the clock.
static System.Threading.Timer timer = new(CallBack, null, 0, 0);
static void CallBack(object? state)
{
var now = DateTime.Now;
timer.Change(1000 - now.Millisecond, 0);
// Console.WriteLine(now + " " + now.Millisecond);
}
Upvotes: 1
Reputation: 16767
If accuracy is an issue and you don't like the accuracy of a timer that raises events, then a simple workaround is to use a polling method.
I'm not saying this is efficient, and you would want to ensure that the task that you execute for each tick completes in less time than the unit you want to fire on, so in this case a second, but it satisfies the requirement of being tightly bound to the system clock:
Action tickAction = () => Console.WriteLine(DateTime.Now);
int lastTick = DateTime.Now.TimeOfDay.Seconds;
while (true)
{
var seconds = DateTime.Now.TimeOfDay.Seconds;
if(lastTick != seconds)
{
lastTick = seconds;
tickAction();
}
}
You could also after each action start a timer with a delay equal to the number of ticks remaining by the next second, but that because a bit overkill for a 1 second timer. If however the time interval was variable, or the time the action takes to execute might exceed the next window, then it might make enough sense to do it in a timer based way.
Overall the event processing loop and whatever else is going on in the background can affect the accuracy even of this solution, having more context on the action that you want to execute on each second would be helpful to produce a more commercially viable solution.
Upvotes: 0