E-Bat
E-Bat

Reputation: 4892

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();

Upvotes: 1

Views: 1465

Answers (1)

Scott Chamberlain
Scott Chamberlain

Reputation: 127603

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();

Upvotes: 2

Related Questions