C # .NET 2 Threading.Timer - drift time

I have a dll consumed by a service. Its main task is to run every X minutes and perform some system checks. In my dll, I have a top-level class that declares System.threading.timer and Timercallback. The class constructor initializes timerCallback with my stream function. In my Onstart handler, I initialize the timer with timercallback and next time set the response time and interval. In my case, it is every 10 minutes. Usually there is nothing to do in these 10-minute checks, but the service is forced to do something at least once a day at a given time.

My problem: I find that during testing, the daily check time runs every day, slowly moving away from the desired start time of 8.30. for example, for more than 20 days, my time drifted from 08.30 to 08.31.35. He drifts about 4-6 seconds every day.

My question is: does anyone know why time is drifting like this and how can I make it stick to its allotted time?

thanks

+6
source share
5 answers

Time "drifts" because the timer is simply not accurate. If you need to run your code as close to a certain interval as possible, you can do something like this:

public void MyTimerCallback(object something) { var now = DateTime.UtcNow; var shouldProbablyHaveRun = new DateTime( now.Year, now.Month, now.Day, now.Hour, now.Minute - (now.Minute % 10), 0); var nextRun = shouldProbablyHaveRun.AddMinutes(10.0); // Do stuff here! var diff = nextRun - DateTime.UtcNow; timer.Change(diff, new TimeSpan(-1)); } 

... if you are using an instance of System.Threading.Timer . Change the example if you use any other type of timer (there are several!).

+6
source

Why not check every minute if the action needs to be completed?

t

 if (DateTime.Now.Minute % 10) == 0 
0
source

it takes a certain amount of time to complete the operations you perform in the timer label handler, so it makes sense that this does not happen every 10 minutes until the second, especially if you plan the next wake up after performing your checks, etc. if you’ve been checking the answer all the time, it’s time to do it, you should make your timer more frequent in order to satisfy the required resolution, and trust your check when it should do something to make sure that it is. you will probably need some persistence to make sure that it is not executed twice (if it is important) in case there is a stop / restart, and the state of knowledge whether it has already been started is not yet in memory.

0
source

Here is my trick:

 while ((DateTime.Now - lastRunTime).TotalSeconds < 600) CurrentThread.Sleep(1000); 

or just register a window timer and execute in response to an event / callback

 public static void Main() { System.Timers.Timer aTimer = new System.Timers.Timer(); aTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent); // Set the Interval to 600 seconds. aTimer.Interval=600000; aTimer.Enabled=true; Console.WriteLine("Press \'q\' to quit the sample."); while(Console.Read()!='q'); } // Specify what you want to happen when the Elapsed event is raised. private static void OnTimedEvent(object source, ElapsedEventArgs e) { Console.WriteLine("10 minutes passed!"); } 
0
source

Timers are not accurate, just approximate. Do not use the "just add 10 minutes" logic. Each time your timer fires, you need to check the time slope and adjust it.

eg. If you say "wake me up in 10 minutes" and it wakes you up in 10 minutes 1sec, then the next timer should be 9min 59 seconds, not 10 minutes.

In addition, you want to set your next timer at the end of your logic.

eg. let's say you want to run taskA every 10 minutes, and it takes 2 seconds to start. Your timer starts, and after 10 minutes it wakes up to start taskA. It starts, ends, now you add 10 minutes. But it took 2 seconds to complete your task. Thus, 10 minutes from the moment your code is launched will be distorted for 2 seconds.

What you need to do is predict the next time you need to work, and find the difference between time and then and set a timer for that difference.

0
source

Source: https://habr.com/ru/post/903377/


All Articles