C# 在 Windows 服务中使用 Thread.Sleep()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/998142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:11:07  来源:igfitidea点击:

Using Thread.Sleep() in a Windows Service

c#multithreadingwindows-servicessleep

提问by matt

I'm writing a windows service that needs to sleep for long periods of time (15 hrs is the longest it will sleep, 30 mins is the shortest). I'm currently using Thread.Sleep(calculatedTime)to put my code into sleep mode. Is Thread.Sleep the best option or should I be using a timer? I've been googling this for a while and can't find a concise answer. Since this is a windows service, I don't have to worry about locking the UI, so I can't think of a reason not to use Thread.Sleep.

我正在编写一个需要长时间睡眠的 Windows 服务(15 小时是最长的睡眠时间,30 分钟是最短的)。我目前正在使用Thread.Sleep(calculatedTime)将我的代码置于睡眠模式。Thread.Sleep 是最好的选择还是我应该使用计时器?我已经在谷歌上搜索了一段时间,找不到简洁的答案。既然是windows服务,不用担心锁定UI,所以想不出不使用Thread.Sleep的理由。

Any insight would be appreciated.

任何见解将不胜感激。

采纳答案by Mitchel Sellers

I would use a timer, Thread.Sleep, could cause a blocking piece that could prevent the service from shutting down.

我会使用一个计时器 Thread.Sleep,它可能会导致阻止服务关闭的阻塞部分。

If the interval is that wide spread, and regular, you might just schedule it as well. But if you are talking about long, non-consistent intervals, then yes a Timer would be better.

如果时间间隔如此广泛且规律,您也可以安排它。但是,如果您谈论的是长时间的、不一致的间隔,那么是的,计时器会更好。

回答by Dan Herbert

It's generally regarded as bad practice to use Thread.Sleep()in a lot of cases.

Thread.Sleep()在很多情况下使用它通常被认为是不好的做法。

If you want the service to run in the background, you should use a timer.

如果您希望服务在后台运行,您应该使用计时器。

If the service only needs to be run at scheduled intervals, I'd recommend you look into using Windows task scheduler to allow Windows to run the application when you need it to.

如果该服务只需要按计划的时间间隔运行,我建议您考虑使用 Windows 任务调度程序来允许 Windows 在您需要时运行该应用程序。

回答by Remus Rusanu

You should not pre-calculate such large amounts of time and sleep for hours. Sleep for a minute at best, then wake up and re-calculate the time, sleep again for no more that a minute. I assume the calculation is very cheap or it can be made very cheap with caching. The problem my advise is trying to mitigate is that computer clocks are surprisingly 'jumpy', mostly due to time drift corrected by network time service, also because of daylights savings and not least because user adjusting the clock. So is better to constantly recompute the time for such long intervals, even if it means waking up every minute or so. And don't be surprised (ie. don't assert) if you wake up in the 'past', clocks can adjust back in time.

您不应该预先计算如此大量的时间和睡眠数小时。最多睡一分钟,然后醒来重新计算时间,再睡一分钟。我认为计算非常便宜,或者可以通过缓存使其非常便宜。我的建议试图缓解的问题是计算机时钟出人意料地“跳跃”,主要是由于网络时间服务纠正了时间漂移,还因为夏令时,尤其是因为用户调整了时钟。所以最好不断地重新计算这么长的时间间隔,即使这意味着每分钟左右醒来一次。如果您在“过去”醒来,请不要感到惊讶(即不要断言),时钟可以及时调整回来。

回答by Kevin Pullin

Another thing to consider is that threads are finite resources and each thread consumes a portion of memory (1MB?) for the its stack. They may also increase load for the scheduler.

另一件要考虑的事情是线程是有限的资源,每个线程为其堆栈消耗一部分内存(1MB?)。它们还可能增加调度程序的负载。

Now, if your service isn't doing much else the wasted space is trivial, but it is wise to be aware of this before you start allocating multiple threads. Using a ThreadPool and/or Timers is much more efficient.

现在,如果您的服务没有做太多其他事情,那么浪费的空间是微不足道的,但是在开始分配多个线程之前意识到这一点是明智的。使用 ThreadPool 和/或 Timers 效率更高。

回答by Carlos A. Ibarra

Since a service may be asked to stop at any time by the Service Control Manager, your thread should always be ready to respond to these requests, so you should not use Thread.Sleep(). Instead, create a manual-reset event in the main thread and use its WaitOne method with a timeout in your worker thread. WaitOne will return false when the time expires.

由于服务控制管理器可能会随时要求停止服务,因此您的线程应始终准备好响应这些请求,因此您不应使用 Thread.Sleep()。相反,在主线程中创建一个手动重置事件,并在您的工作线程中使用它的 WaitOne 方法和超时。WaitOne 将在时间到期时返回 false。

When your service class's OnStop or OnShutdown methods are called, set the event and that will cause WaitOne to return true and you can then exit your worker thread.

当您的服务类的 OnStop 或 OnShutdown 方法被调用时,设置事件,这将导致 WaitOne 返回 true,然后您可以退出您的工作线程。