线程休眠/等待新的一天

发布于 2024-12-04 17:00:27 字数 160 浏览 2 评论 0原文

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

最好的选择是:

  • 继续每秒检查新日期的时间
  • ​​计算直到午夜的秒数并睡眠该时间长度
  • 还有其他吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

若有似无的小暗淡 2024-12-11 17:00:27

不要将 Thread.Sleep 用于此类事情。使用计时器并计算您需要等待的持续时间。

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 */ 委托替换为将按指定时间间隔恢复工作的回调。

编辑:正如评论中提到的,有如果您假设应用程序将等待的“经过的时间”将与现实世界的时间相匹配,则许多事情可能会出错。因此,如果计时对您很重要,最好使用较小的轮询间隔来查明时钟是否已达到您希望工作发生的时间。

更好的是使用 Windows 任务计划程序在所需的时间运行您的任务。这比尝试自己用代码实现要可靠得多。

Don't use Thread.Sleep for this type of thing. 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.

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. This will be much more reliable than trying to implement it yourself in code.

长不大的小祸害 2024-12-11 17:00:27

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

Windows has a task scheduler that handles exactly this duty. Create the program to do that which it is supposed to do. Then set it up as a scheduled task.

妳是的陽光 2024-12-11 17:00:27

只需计算等待时间并运行异步计时器,就可以避免等待时额外消耗 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);

Just calculate a period to wait and run an asynchronous timer in this way you can avoid extra CPU consuming whilst waiting:

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);
三五鸿雁 2024-12-11 17:00:27

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

每天有 60*60*24 = 86,400 秒,因此如果您提前达到限制,您可能会进行大量检查。此外,忙等待会浪费 CPU 周期,并且会减慢正在运行的所有其他操作。

您应该计算直到午夜的秒数并睡眠那么长时间(尽管我相信睡眠参数需要毫秒而不是秒,因此可能需要一个简单的转换)。

编辑:

计算然后睡眠的另一个好处是,如果用户想通过更改时钟来绕过您的限制,他们将无法做到(因为时钟读数午夜不会唤醒进程,因为需要不断检查)。然而,通过更好地了解程序内部的工作原理,用户可以在每次即将达到操作限制时将时钟更改为几乎午夜,从而导致线程在几分钟甚至几秒钟内唤醒。这是一个比您的第一个建议更复杂的利用,但它是可以做到的。

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. Additionally, busy waiting is a waste of CPU cycles, and it will slow down everything else that is running.

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

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.

著墨染雨君画夕 2024-12-11 17:00:27

这就是我如何让线程休眠到明天早上 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);

This is how I make a thread sleep till tomorrow 6AM

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文