Pavan Navali
Pavan Navali

Reputation: 242

Timer takes more time

Scenario: In a Winform application(C#), I have a Datagridview in which I have to display 4 countdown timers in the format "mm:ss". Time Interval must be 1000ms.

I was counting the timer down in the elapsed event of system.timers.timer.

On all 4 timers I'm starting to countdown from 2 mins (02:00).

Issue: It takes more time(125 seconds) than 2 mins, to reach 00:00. Similarly for 4 mins it takes 7-10 more(247 -250) seconds to reach 00:00

Upvotes: 1

Views: 846

Answers (3)

Austin Salonen
Austin Salonen

Reputation: 50235

First off you should run this little test and see the drift in near real-time. I lose a 1 second after 72 timer elapsed events (this is with very little actual work).

using (var timer = new Timer(1000))
{
    var start = DateTime.Now;
    var i = 0;
    timer.Elapsed += (sender, args) => Console.WriteLine("{0} -> {1}", ++i, (DateTime.Now - start).TotalMilliseconds);
    timer.Start();
    Thread.Sleep(130*1000);
}

I'm not sure how precise your app needs to be but you can get "good enough" by using the delta between the start time & now and subtracting that from your initial value and killing the timer at zero. You will lose seconds with this approach and there's a reasonable chance that lost second could happen @ 0:00 causing a -0:01 tick, which you will need to handle.

var countdownSeconds = 120;
var startedAt = DateTime.Now;

var timer = new Timer(1000);    
timer.Elapsed += (sender, args) => Display(countdownSeconds - (int)((DateTime.Now - startedAt).TotalSeconds));
timer.Start();

//- be sure to dispose the timer

Upvotes: 0

Tergiver
Tergiver

Reputation: 14517

If you need time resolution of that type (i.e. actual clock or countdown clock), you should use the real-time clock.

You still use a timer with sub-second resolution to fire frequently enough for display purpose, but you don't add up those times, you use the real-time clock to get the real elapsed time (DateTime.Now - startTime).

Upvotes: 0

nyxthulhu
nyxthulhu

Reputation: 9762

Timers on systems are somewhat of an inaccurate beast. Better systems generally provide better timers but even the best system has slippage.

You also need to remember that your process isn't going to be in "full control" 100% of the time, it will at times be pushed into the background and have to share the processor with other applications so whilst it's does its best to keep track of the time.

What you probably want is a High Precision Timer (aka stopwatch) in C#. Have a look at This thread and This article on selecting timer mechanisms for some more information.

Upvotes: 2

Related Questions