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