4

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

假设我有(而且我确实有)一个正在等待WaitHandle的 Windows 服务,当它被唤醒时,它会像我在下面的流程图中显示的那样进入等待旋转

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

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

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

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

4

6 回答 6

5

我看不到您从计时器中获得任何好处。无论如何,您的睡眠呼叫本质上都是一个计时器,并且您不会成为带宽占用者,因为睡眠会产生时间片。有一个明确的计时器唤醒并打电话给你只会使代码复杂化。

我不会真的说你在做旋转等待,因为我通常认为旋转等待是不睡觉的东西。它只是消耗了所有等待 go 信号的处理器时间。

于 2009-07-08T17:44:22.103 回答
2

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

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

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

于 2009-07-08T17:53:54.113 回答
1

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

于 2009-07-08T18:11:01.473 回答
1

我认为这真的取决于你的要求:

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

Timer 对于案例 1 似乎很容易,而 Thread.Sleep 对于案例 2 似乎很容易,尽管 Timer 和 Thread.Sleep 两者都可以。

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

于 2009-07-09T09:03:53.867 回答
1

轮询很糟糕,而且几乎总是可以避免的。有时对于琐碎的事情,它比避免它所需的复杂性要好。

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

此外,不要Sleep()长时间使用严肃的代码(如服务)。您可以做的唯一阻塞是WaitFor[Single|Multiple]Objects(...)句柄列表包含一个在需要关闭进程时触发的事件。查找您呼叫的任何地方Sleep(millisec)并将其替换为WaitForSingleObjects(g_shutdownEvent, millisec).

于 2009-07-30T23:13:14.910 回答
0

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.

于 2009-07-30T23:38:17.340 回答