E-Bat E-Bat - 1 month ago 12
C# Question

Run DispatcherTimer at every exact minute

The following dispatcher runs every 1 minute, counting from the time is invoked its Start() method...but what I actually need is that it ticks on every change in the minute component of the system time. Any idea?
This is a windows application (WPF).

DispatcherTimer hourTimer = new DispatcherTimer(DispatcherPriority.Normal)
{
Interval = new TimeSpan(0, 1, 0)
};
hourTimer.Tick += (sender,e) => { renderTime(); };
hourTimer.Start();

Answer

You can't get a "metronome quality beat" from any timer that uses a single thread to execute the tick. This is because the thread may be blocked when the tick needs to happen.

The best you can do is calculate the time till the next tick and reset the duration at the start of the tick event.

var now = DateTime.UtcNow;
var nextMinute = now.AddTicks(-(now.Ticks%TimeSpan.TicksPerMinute)).AddMinutes(1);

DispatcherTimer hourTimer = new DispatcherTimer(DispatcherPriority.Normal)
{
    Interval = nextMinute - DateTime.UtcNow
};
hourTimer.Tick += (sender, e) =>
{
    var correctionNow = DateTime.UtcNow;
    var timeCorrection = correctionNow.AddTicks(-(correctionNow.Ticks % TimeSpan.TicksPerMinute)).AddMinutes(1);

    hourTimer.Interval = timeCorrection - DateTime.UtcNow;
    renderTime();
};
hourTimer.Start();