线程休眠/等待直到新的一天

本文关键字:新的一天 等待 休眠 线程 | 更新日期: 2023-09-27 18:08:53

我正在循环中运行一个进程,该进程对每天执行的操作数量有限制。当它达到这个限制时,我现在让它在循环中检查时间,看看它是否是一个新的日期。

最好的选择是:

  • 保持每秒钟检查时间的新日期
  • 计算到午夜的秒数,并睡眠的时间长度
  • 别的吗?

线程休眠/等待直到新的一天

不要使用Thread。这种事睡一觉。使用计时器计算你需要等待的时间

var now = DateTime.Now;
var tomorrow = now.AddDays(1);
var durationUntilMidnight = tomorrow.Date - now;
var t = new Timer(o=>{/* Do work*/}, null, TimeSpan.Zero, durationUntilMidnight);

/* Do Work */委托替换为在指定的时间间隔内恢复您的工作的回调。

Edit:正如评论中提到的,如果假定应用程序等待的"经过的时间"与实际时间匹配,那么很多事情都可能出错。由于这个原因,如果时间对您很重要,那么最好使用较小的轮询间隔来确定时钟是否达到了您希望工作发生的时间。

更好的是使用Windows任务调度程序在所需的时间运行任务。这比你自己在代码中实现要可靠得多。

Windows有一个任务调度程序来处理这个任务。创建程序来完成它应该做的事情。然后将其设置为计划任务。

只需计算等待周期并以这种方式运行异步计时器,就可以避免在等待时额外消耗CPU:

var nextDateStartDateTime = DateTime.Now.AddDays(1).Subtract(DateTime.Now.TimeOfDay);
double millisecondsToWait = (nextDateStartDateTime - DateTime.Now).TotalMilliseconds;
System.Threading.Timer timer = new Timer(
    (o) => { Debug.WriteLine("New day comming on"); },
    null,
    (uint)millisecondsToWait
    0);

考虑到您提供的两个选项:

每天有60*60*24 = 86,400秒,所以如果你提前达到极限,你可能会做很多检查。此外,繁忙的等待会浪费CPU周期,并且会减慢其他正在运行的程序的速度。

您应该计算到午夜的秒数和睡眠时间(尽管我认为sleep参数需要ms而不是s,因此可能需要简单的转换)。

编辑:

计算然后睡觉的另一个好处是,如果用户想通过更改时钟来绕过您的限制,他们将无法做到(因为时钟读取午夜不会像持续检查那样唤醒进程)。但是,通过更好地了解程序的内部工作方式,用户可以在每次操作即将达到极限时将时钟更改为几乎午夜,从而使线程在几分钟甚至几秒钟内唤醒。这是一个比你的第一个建议更复杂的开发,但它是可以做到的。

这就是我如何让一个线程睡到明天早上6点

minutesToSleep = (int)(new DateTime(DateTime.Now.AddDays(1).Year, DateTime.Now.AddDays(1).Month, DateTime.Now.AddDays(1).Day, 6, 0, 0) - DateTime.Now).TotalMinutes;
Console.WriteLine("Sleeping for {0} minutes (until tomorrow 6AM)", minutesToSleep);