如何以反复的方式使定时器点火

时间:2013-12-02 15:20:19

标签: c# .net windows multithreading timer

我有一个计时器,我想在星期一下午5点每个到期。在测试应用程序时,一旦它在星期一到达下午5点,我的任务就会被解雇。

但是,当我在下午5点将系统日期和时间更改为下一周时,任务不会触发。这是我的代码:

Timer timer = new Timer(callback, application, timeToEnd, TimeSpan.FromDays(7));

我觉得它与TimeSpan.FromDays(7)部分有关。有什么想法吗?

5 个答案:

答案 0 :(得分:2)

这对Timer不是很好用。您应该创建一个可以执行所需操作的控制台应用程序,然后使用Windows Scheduler或第三方计划工具进行计划。

否则,更安全的做法是将定时器设置为以间隔运行(1分钟?)并检查系统时钟以查看是否需要运行(例如是它在5点钟的1分钟内?)

答案 1 :(得分:1)

所有计时器都不依赖于系统时间。

更改时钟不会影响System.Windows.Forms.TimerSystem.Timers.TimerSystem.Threading.Timer

如果您需要处理这些情况,则必须依赖SystemEvents.TimeChanged

否则,您可以定期检查DateTime.Now.DayOfWeek == DayOfWeek .Monday

答案 2 :(得分:1)

如果您不想依赖Window Task Scheduler之类的外部服务,则必须创建一个定时触发的计时器(例如每分钟)并检查当前时间,如果当前时间已经过去下一个到期时间它实际执行所需的操作(包括设置下一个到期时间)。

除非您在低功率设备上运行,否则每分钟执行一次时间检查不应该是一个问题。

将时钟向前移动一周是一个非常极端的措施,但夏令时也可以移动时钟,特别是在虚拟机上,您可能会有一些意外的时钟漂移。这就是为什么在大多数时间以固定间隔检查当前时间比在未来某个时间设置定时器更好的原因。

说到夏令时,您需要处理时钟向后移动一小时的情况,以防您想要在该时间间隔内执行活动。

答案 3 :(得分:1)

你现在遇到了麻烦。我们要求框架在x days, y hours, z minutes之后通知您。所以计时器会在你告诉它的时间之后准确发射。

我知道这不是正确的方法,但这会奏效。

SystemEvents.TimeChanged += SystemEvents_TimeChanged;

static void SystemEvents_TimeChanged(object sender, EventArgs e)
{
    timer.Dispose();//Dispose your previous timer
    SetTimerAgain();//Call the method which sets the timer again. you're done
}

我推荐“Windows预定任务”,但出于某种原因,你不能这样做。

你也可以像@giammin建议的那样运行一个定期计时器。

TimerCallback callback = (state) =>
{      
    var now = DateTime.Now; 
    if(now.DayOfWeek == DayOfWeek.Monday 
     && now.TimeOfDay.Hours == 17 && now.TimeOfDay.Minutes == 0)
    {
        MyMethod();
    }
};

Timer timer = new Timer(callback, application, 0, 10000);//10seconds

使用后一种方法,你应该保护自己不要在同一天一次又一次地调用该方法。

答案 4 :(得分:1)

如果您想要在特定时间点火的计时器,请使用Waitable Timer。不幸的是,.NET库没有该计时器的包装器。我有一段时间写了一篇文章。该文章已不再在线提供,但您可以从http://mischel.com/pubs/waitabletimer.zip下载源代码。

那就是说,听起来你拥有的是catnap program。像其他人建议的那样做,并使其成为您使用计划任务控制的简单控制台应用程序。