Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windows服务如何减慢无限循环_C#_Service - Fatal编程技术网

C# Windows服务如何减慢无限循环

C# Windows服务如何减慢无限循环,c#,service,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) { //Servic

我被告知制作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(大数字)是一种不好的做法,这是真的吗?如果是这样的话,我如何绕过循环不断运行并使用大量资源?实际上,现在循环中没有任何操作,它都在我的计时器的ticketvent中处理,我有一个循环的唯一原因是停止runProc结束


非常感谢,如果我解释得不好,很抱歉。睡眠不好,因为它不容易被打断1

我通常更喜欢使用a或类似的:

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
     }
  }
}
希望您能理解要点,而不是一个很好的代码示例

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



1从下面的评论中总结我的立场-它只能被诸如
Thread.Abort
Thread.Interrupt
之类的钝工具打断,这两种工具都有一个共同的缺陷(或多或少),即它们也可以在代码中的其他不同位置引入相关异常。如果您可以保证线程实际上位于
线程.Sleep
调用中,则后者可能没问题-但是如果您可以做出这样的保证,您通常还可以安排使用一种不太直率的线程间通信机制,如我在本回答中建议的机制。

我总是使用主无限循环编写服务,而不是使用计时器。在循环内部,我检查是否有工作要做,如果有,我就做,如果没有,我调用
Thread.Sleep()
。这意味着,只要有工作要做,循环就会不断迭代,以尽可能快的速度运行。当工作队列“干涸”时,它会休眠一点(几秒钟或几分钟),同时有更多的工作可用


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

这是
runProc
唯一将
\u isRunning
设置为false的方法吗?如果是,这是无限循环,你在哪里看到线程的迹象。在循环中睡眠(大数字)是不好的做法?嘿,蓝蒙克,它会导致不同的东西停止,而且它不准确?这就是我以前设计的所有服务的方式,但对于一个我知道只需每1h45m检查一次的服务来说,这似乎是一种过度使用。我目前正在研究预定的任务,所以非常感谢!同意,我会考虑一个预定的任务在那种情况下。但是,当然,问题在于细节。我从来没有遇到过用
Interrupt()
调用唤醒线程的问题。被中断的线程只需要捕获适当的异常并退出其主循环。@acfrancis-它比
线程的危险性要小。Abort
,但在我看来,危险性不大-请注意,您不知道是什么导致线程进入WaitSleepJoin状态-除其他外,它可能正在等待锁定-嗯,你最好设计好你的代码,在它扰乱任何共享状态之前抓住所有锁,否则你可能会有问题。我感觉我们在我们的服务中编写了非常不同的代码。如果我的一个线程被中断,它要么退出(如果服务停止),要么捕获异常,记录它并再次迭代循环以执行下一个可用的工作单元。这对我来说总是很好。@acfrancis-我的问题是
线程。睡眠
不是唯一一个
ThreadInterruptedException
可能突然抛出的地方-我宁愿使用可靠的线程间通信形式,在这里我表示“在这段代码中,我将响应一个特定的信号(或一组信号)”