Windows Service如何减慢无限循环

本文关键字:无限循环 何减慢 Service Windows | 更新日期: 2023-09-27 18:37:12

我被告知制作Windows服务的方式如下:

Thread serviceThread = new Thread(new Thread(runProc())
Boolean isRunning = true;
if (_isRunning)
   {
      serviceThread.Start();
   }else
      close and log service
void runProc()
{
   while(_isRunning)
   {
      //Service tasks
   }
   _isRunning = false;
}

到目前为止,这对我来说效果很好,但现在我需要做一个有很大的突破的服务,一次最多 2 小时。此外,我已经开始使用计时器,因此除了停止 runProc() 一遍又一遍地运行之外,在无限循环中什么也没做,我可以想象这很糟糕,因为线程正在被制作和重新制作。

我的问题是,我已经读到将 Thread.Sleep(大数字)放在那个 while(_isRunning) 无限循环中是一种不好的做法,这是真的吗?如果是这种情况,我如何绕过不断运行并使用大量资源的循环?现在循环中实际上什么也没做,它都是在我的计时器的 tickevent 中处理的,我有一个循环的唯一原因是停止 runProc 结束。

非常感谢,对不起,如果我解释得不好

Windows Service如何减慢无限循环

Thread.Sleep不好,因为它不能(容易)中断1。

我通常更喜欢使用ManualResetEvent或类似

class abc {
  Thread serviceThread = new Thread(new Thread(runProc())
  ManualResetEvent abort = new ManualResetEvent(false);
  void Start(){
      serviceThread.Start();
  }
  void Stop(){
     abort.Set();
     serviceThread.Join();
  }
  void runProc()
  {
     while(!abort.WaitOne(delay))
     {
      //Service tasks
     }
  }
}

希望您能理解要点,而不是一个很棒的代码示例。

delay可以根据需要大或小(并且可以在每个循环期间任意重新计算)。WaitOne调用会将此线程的进度延迟 delay 毫秒,或者,如果调用Stop,将导致循环立即退出。


1从下面的评论中总结我的立场 - 它只能被像 Thread.AbortThread.Interrupt 这样的生硬工具打断,它们都(或多或少)共享失败,它们也可以在代码中的其他各个位置引入相关的异常。如果你能保证线程实际上在Thread.Sleep调用中,那么后者可能没问题——但如果你能做出这样的保证,你通常也可以安排使用一个不太生硬的线程间通信机制——比如我在这个答案中建议的那个。

我一直使用主无限循环而不是计时器编写服务。在循环中,我检查是否有任何工作要做,如果是,我做工作,如果没有,我打电话给Thread.Sleep()。这意味着只要有工作要做,循环就会不断迭代,尽可能快地运行。当工作队列"干涸"时,它会休眠一点(几秒钟或几分钟),同时有更多的工作可用。

这对于服务器上的后端作业总是非常有效,因为白天(和晚上)都有源源不断的新工作要做。如果您的月经很大,没有工作,服务将多次唤醒以检查,然后重新进入睡眠状态。你可能喜欢或不喜欢。只要检查很快,就不应该成为问题。另一种方法是使用计划任务(或数据库作业),以便您知道工作将在一天中的特定时间完成。在某些情况下,这是一种更好的方法。