对于 Windows 服务,等待旋转和计时器哪个更好?

发布于 2024-07-26 16:24:55 字数 719 浏览 5 评论 0原文

这个关于 Windows 服务定时器的问题让我思考:

假设我有(我确实有)一个正在等待 WaitHandle 的 Windows 服务醒来后,它会陷入等待旋转,就像我在下面的流程图中所示的

等待旋转图http:// www.86th.org/waitspin.jpg

我很好奇使用计时器是否会比 等待自旋循环(有时称为自旋等待)。 老实说,除了我自己的修补之外,我从未将计时器用于任何其他目的。

我没有任何转换的计划,除非差异很大并且使用计时器的好处是惊人的。 然而,我对人们对这个项目未来发展的不同想法非常感兴趣。

让我知道这是否应该是一个维基

This question about Timers for windows services got me thinking:

Say I have (and I do) a windows service thats waiting on a WaitHandle and when woken, it dives into a wait-spin like I have shown below in a flowchart

wait spin diagram http://www.86th.org/waitspin.jpg

I'm curious if using a timer would be better than a wait-spin loop (sometimes called a spin-wait). I'll be honest, I've never used timers for anything other than my own tinkering.

I don't have any plans to switch unless the differences are profound and the benefits of using a Timer are amazing. However, I'm very interested on peoples thoughts on one vs the other for future development of this project.

Let me know if this should be a wiki

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

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

发布评论

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

评论(6

赴月观长安 2024-08-02 16:24:55

我不认为你从计时器中得到任何好处。 无论如何,您在睡眠呼叫中本质上表现为计时器,并且您不会占用带宽,因为睡眠会占用时间片。 有一个显式的定时器唤醒并给你打电话只会使代码变得复杂。

我实际上不会说您正在执行旋转等待,因为我通常认为旋转等待是不休眠的东西。 它只是消耗了所有等待 go 信号的处理器时间。

I don't see you getting any benefit out of a timer. You are essentially behaving as a timer anyway with your sleep call, and you are not being a bandwidth hog since sleep yields up the time slice. Having an explicit timer wake up and call you is just going to complicate the code.

I wouldn't really say that you are doing a spin-wait, since I generally think of a spin-wait as something that doesn't sleep. It just burns all it's processor time waiting for the go signal.

顾铮苏瑾 2024-08-02 16:24:55

休眠线程和等待超时句柄本质上是同一件事。 我猜想定时器本质上是使用睡眠来实现的,所以也没有太大区别。 换句话说,您可以通过在单个循环中等待超时句柄并检查释放等待的原因(数据可用或超时)来简化代码,而不是实现单独的等待和睡眠循环。 比独立循环稍微高效一些。

理想情况下,您根本不会使用睡眠,而只是依赖数据生成代码来正确引发您的消费代码正在等待的事件,并在事件源消失时使用较长的超时来处理。

如果数据是外部的,例如在套接字或其他输入设备上,则通常可以将句柄设置为允许等待数据变得可用 - 在这种情况下不需要轮询,因为当数据准备好时,事件将始终发出信号用于消费。

Sleeping a thread and waiting on a handle with a timeout are basically the same thing under the covers. I would guess that timers are essentially implemented using sleep, so not much difference there, either. In other words, you could simplify your code by waiting on the handle with a timeout in a single loop and checking to see why the wait was released (data available or timeout), rather than implementing separate wait and sleep loops. Slightly more efficient than independent loops.

Ideally, you would not use sleep at all and simply depend on the data-generation code to correctly raise the event your consumption code is waiting on, with a longish timeout to handle when the event source has gone away.

If the data is external, such as on a socket or other input device, then the handle can generally be set to allow waiting for data to become available - no need to poll in that case since the event will always be signaled when data is ready for consumption.

樱花落人离去 2024-08-02 16:24:55

我们使用线程。 它们不仅像计时器一样执行,而且还为我们提供了一个句柄,以便在线程休眠时执行其他操作。

We use threads. Not only do they perform like a timer, but they give us a handle to perform other operations while the thread is sleeping.

看透却不说透 2024-08-02 16:24:55

我认为这实际上取决于您的要求:

  1. 每隔运行任务 5 分钟(例如,12:00、12:05、12:10,...
  2. )完成当前任务, 5 分钟后运行下一个任务。

对于情况 1,Timer 似乎很容易,而对于情况 2,Thread.Sleep 似乎很容易,尽管 Timer 和 Thread.Sleep 可以同时完成这两个任务。

事实上,我对类似的问题发表了更长的评论(包括对案例1的一些考虑)(Windows 服务计划执行)。

I think it really depends on your requirement:

  1. Run the task every 5 min (for example, 12:00, 12:05, 12:10, ...)
  2. Upon completing the current task, run the next task after 5 min.

Timer seems to be easy for the case 1 and Thread.Sleep seems to be easy for the case 2, even though Timer and Thread.Sleep can do both of them.

I , in fact, put a longer comment (including some consideration on the case 1) for a similar question (Windows service scheduled execution).

泪意 2024-08-02 16:24:55

轮询是不好的,而且几乎总是可以避免的。 有时,对于微不足道的事情来说,它比避免它所需的复杂性更糟糕。

您正在哪个来源投票“有数据?” 你不能变成某种句柄等待吗?

另外,不要在严肃的代码(如服务)中长时间使用 Sleep() 。 您可以执行的唯一阻止操作是 WaitFor[Single|Multiple]Objects(...),其中句柄列表包含一个在需要关闭进程时触发的事件。 找到您调用 Sleep(millisec) 的所有位置,并将其替换为 WaitForSingleObjects(g_shutdownEvent, millisec)

Polling is bad, and nearly always avoidable. Occasionally for trivial things it's less bad than the complexity needed to avoid it.

What source are you polling for "Has data?" that you can't turn into some kind of handle wait?

Also, don't Sleep() in serious code (like a service) for any significant amount of time. The only blocking you can do is WaitFor[Single|Multiple]Objects(...) where the list of handles includes an event that is fired when it's time to shut down the process. Find everywhere you're calling Sleep(millisec) and replace it with WaitForSingleObjects(g_shutdownEvent, millisec).

后eg是否自 2024-08-02 16:24:55

正如 Raymond Chen 所解释的那样,“是的,无论如何。” 如果您无法找到在数据准备好后收到通知的方法 - 那么您的 SOL.

As Raymond Chen explains, "Yeah, whatever." If you can't figure out a way to get notified when your data is ready - then your SOL.

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