如何根据时钟使定时器以完全相同的间隔启动?

时间:2016-06-02 13:26:34

标签: c# .net wpf timer

我需要帮助设置这样的计时器:

间隔1分钟的计时器从12:25:25(HH:MM:SS)开始,第一次在12:26:00然后在12:27:00开始,依此类推。或者采取另一个15分钟的间隔计时器,从12:07:25开始,然后在12:15:00然后在12:30:00休息,依此类推。

我设法让1分钟计时器像这样:

OneMinute.Interval = TimeSpan.FromSeconds(60 - DateTime.Now.Second);

它完美无缺,但我仍然需要计算剩下多少分钟,直到时钟达到15,30,45或60.

有没有办法让这种情况发生?

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:3)

您可以使用特殊的初始化计时器:

  • 计算下一个所需刻度的时间跨度
  • 将初始间隔设置为该时间范围
  • 启动计时器
  • 在第一次勾选后,将间隔设置为所需的时间跨度。

StartPlainTimer方法

// Define other methods and classes here
private static DispatcherTimer StartPlainTimer(TimeSpan interval)
{
    var millisecondsLeftToday = DateTime.Now.TimeOfDay.TotalMilliseconds;
    var millisecondsInterval = interval.TotalMilliseconds;
    var firstInterval = millisecondsInterval - ((millisecondsLeftToday / millisecondsInterval) % 1) * millisecondsInterval;
    var timer = new DispatcherTimer();
    timer.Interval = TimeSpan.FromMilliseconds(firstInterval);
    timer.Tag = interval;
    Console.WriteLine("Start: " + DateTime.Now);
    timer.Tick += ResetInterval;
    timer.Start();
    return timer;
}

private static void ResetInterval(object sender, EventArgs args)
{
    var timer = sender as DispatcherTimer;
    timer.Interval = (TimeSpan)timer.Tag;
    timer.Tick -= ResetInterval;
}

<强>用法

// Example for a timer that runs all 3 seconds
var timer = StartPlainTimer(TimeSpan.FromSeconds(3));
timer.Tick += (s, e) => Console.WriteLine(DateTime.Now);

<强>输出

Start: 02.06.2016 16:26:41
02.06.2016 16:26:42
02.06.2016 16:26:45
02.06.2016 16:26:48

更详细的时间格式显示该方法的不准确性:

15秒示例:

Start: 06.02.2016 04:44:50.902 
06.02.2016 04:45:00.017 
06.02.2016 04:45:15.018 
06.02.2016 04:45:30.024 
06.02.2016 04:45:45.022 
06.02.2016 04:46:00.027 
06.02.2016 04:46:15.031 
06.02.2016 04:46:30.036

因此,如果100 ms的准确度足够,那么该解决方案应该没问题。

答案 1 :(得分:2)

我建议调查Quartz.net等框架

Quartz.net

自Windows 7以来.NET计时器的问题在于它们具有~15ms的分辨率,因此您可以看到随着时间的推移而滑动,即使您设法在特定时间精确地启动它。

编辑:Quartz.net示例代码

trigger = TriggerBuilder.Create()
    .WithIdentity("trigger3", "group1")
    .WithCronSchedule("0 42 10 * * ?")
    .ForJob("myJob", "group1")
    .Build();

这将构建一个触发器,每天在10:42触发。虽然这并没有给出您正在寻找的确切答案,但您可以以CRON方式安排任务。所以你可以像这样实现15分钟的执行间隔。您需要阅读更多文档才能理解这个框架。

答案 2 :(得分:2)

经过一些测试和计算后,我能够成功地将分钟留到时间15分。

以下是:

FifteenMinutes.Interval = TimeSpan.FromMinutes(15 - DateTime.Now.Minute % 15);

谢谢大家的帮助!这是迫切需要的。