Windows Service如何减慢无限循环

时间:2013-10-28 14:59:59

标签: c# service

我被告知制作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(大数字)放在那个(_isRunning)无限循环中是不好的做法,这是真的吗?如果是这种情况,我如何绕过循环运行并使用大量资源?现在几乎没有在循环中完成任何操作,它都是在我的计时器的处理中处理的,我有一个循环的唯一原因是停止runProc结束。

非常感谢抱歉,如果我解释得很糟糕

2 个答案:

答案 0 :(得分:2)

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通话中,那么后者可能没问题 - 但是如果你可以做出这样的保证,你通常也可以安排使用一个不那么直率线程间通信机制 - 例如我在这个答案中建议的那个。

答案 1 :(得分:0)

我总是用主要的无限循环编写服务,而不是定时器。在循环内部,我检查是否有任何工作要做,如果是,我做了工作,如果不是,我打电话给Thread.Sleep()。这意味着只要有工作要做,循环将继续迭代,尽可能快地运行。当工作队列“干涸”时,它会睡眠一点(几秒钟或几分钟),同时可以进行更多工作。

对于服务器上的后端作业来说,这总是非常有效,因为在一天中(或晚上)有不断的新工作。如果你有很长一段时间没有工作,服务会多次醒来检查,然后再回去睡觉。你可能喜欢或不喜欢。只要检查很快,就不应该成为问题。另一种方法是使用计划任务(或数据库作业),以便您知道工作将在一天中的特定时间完成。在某些情况下,这是一种更好的方法。