简体   繁体   English

线程睡眠/等到新的一天

[英]Thread sleep/wait until a new day

I'm running a process in a loop which has a limit on the number of operations it does per day. 我正在循环中运行一个进程,它对每天的操作数量有限制。 When it reaches this limit I've currently got it checking the the time in a loop to see if it a new date. 当它达到这个限制时,我现在已经检查了循环中的时间,看它是否是一个新的日期。

Would the best option be to: 最好的选择是:

  • Keep checking the time every second for new date 继续检查新日期的每秒时间
  • Calculate the number of seconds until midnight and sleep that length of time 计算直到午夜的秒数并睡眠那段时间
  • Something else? 别的什么?

Don't use Thread.Sleep for this type of thing. 不要将Thread.Sleep用于此类事情。 Use a Timer and calculate the duration you need to wait. 使用计时器并计算您需要等待的持续时间。

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

Replace the /* Do Work */ delegate with the callback that will resume your work at the specified interval. /* Do Work */ delegate替换为将以指定间隔恢复工作的回调。

Edit: As mentioned in the comments, there are many things that can go wrong if you assume the "elapsed time" an application will wait for is going to match real-world time. 编辑:如评论中所述,如果您假设应用程序等待的“已用时间”将与实际时间匹配,则可能会出现许多问题 For this reason, if timing is important to you, it is better to use smaller polling intervals to find out if the clock has reached the time you want your work to happen at. 因此,如果时间对您很重要,最好使用较小的轮询间隔来确定时钟是否已达到您希望工作发生的时间。

Even better would be to use Windows Task Scheduler to run your task at the desired time. 更好的方法是使用Windows任务计划程序在所需的时间运行您的任务。 This will be much more reliable than trying to implement it yourself in code. 这比尝试在代码中自己实现它要可靠得多。

Windows has a task scheduler that handles exactly this duty. Windows有一个任务调度程序 ,可以完全处理这个任务。 Create the program to do that which it is supposed to do. 创建程序以执行它应该执行的操作。 Then set it up as a scheduled task. 然后将其设置为计划任务。

Just calculate a period to wait and run an asynchronous timer in this way you can avoid extra CPU consuming whilst waiting: 只需计算等待时间并以这种方式运行异步计时器,就可以避免在等待时消耗额外的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);

Considering the two options you've provided: 考虑到您提供的两个选项:

There are 60*60*24 = 86,400 seconds per day, so you could potentially do a lot of checking if you hit the limit early. 每天有60 * 60 * 24 = 86,400秒,因此如果您提前达到限制,您可能会进行大量检查。 Additionally, busy waiting is a waste of CPU cycles, and it will slow down everything else that is running. 此外,忙碌的等待会浪费CPU周期,并且会减慢正在运行的所有其他内容。

You should calculate the number of seconds until midnight and sleep that long (although I believe the sleep paramater takes ms rather than s, so a simple conversion may be needed). 你应该计算到午夜之前的秒数并且睡眠时间很长(虽然我认为睡眠参数需要ms而不是s,因此可能需要简单的转换)。

EDIT: 编辑:

An additional benefit of calculating then sleeping is that if a user wants to bypass your restriction by changing the clock, they will not be able to (since the clock reading midnight won't wake the process as it would with continual checking). 计算然后休眠的另一个好处是,如果用户想要通过更改时钟来绕过限制,他们将无法(因为午夜的时钟读数不会像连续检查那样唤醒过程)。 However, with a better understanding of how your program works internally, the user could change the clock to almost midnight every time they are about to reach the limit of operations, causing the thread to wake up in a few minutes or even a few seconds. 但是,通过更好地理解程序在内部的工作方式,用户可以在每次达到操作限制时将时钟更改为接近午夜,从而导致线程在几分钟甚至几秒钟内唤醒。 It's a more complicated exploitation than would be doable with your first suggestion, but it can be done. 这是一个比你的第一个建议可行的更复杂的利用,但它可以做到。

This is how I make a thread sleep till tomorrow 6AM 这就是我如何让线程睡到明天早上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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM