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 结束。
非常感谢,对不起,如果我解释得不好
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.Abort
或 Thread.Interrupt
这样的生硬工具打断,它们都(或多或少)共享失败,它们也可以在代码中的其他各个位置引入相关的异常。如果你能保证线程实际上在Thread.Sleep
调用中,那么后者可能没问题——但如果你能做出这样的保证,你通常也可以安排使用一个不太生硬的线程间通信机制——比如我在这个答案中建议的那个。
我一直使用主无限循环而不是计时器编写服务。在循环中,我检查是否有任何工作要做,如果是,我做工作,如果没有,我打电话给Thread.Sleep()
。这意味着只要有工作要做,循环就会不断迭代,尽可能快地运行。当工作队列"干涸"时,它会休眠一点(几秒钟或几分钟),同时有更多的工作可用。
这对于服务器上的后端作业总是非常有效,因为白天(和晚上)都有源源不断的新工作要做。如果您的月经很大,没有工作,服务将多次唤醒以检查,然后重新进入睡眠状态。你可能喜欢或不喜欢。只要检查很快,就不应该成为问题。另一种方法是使用计划任务(或数据库作业),以便您知道工作将在一天中的特定时间完成。在某些情况下,这是一种更好的方法。