老实说,我不得不说,我认为你在这里有点不走寻常路。
首先,发布的实际代码并没有真正的意义;工作线程正在等待信号,但没有任何原因 - 它实际上并不处于任何类型的循环中或等待资源。其次,如果您确实需要在收到关闭信号后在工作线程中执行一些(可能省略)清理代码,则您的服务可能不会给工作线程足够的时间来进行清理。
但是,更根本的是,您所做的只是将问题移至单独的线程。这可能会保持服务对服务控制器的响应,但它并不能解决设计问题 - 并且它通过使用线程和互斥体增加了很多不必要的复杂性;最终,如果您需要的话,它只会使您的服务更难调试。
假设您需要每 5 秒执行一些代码。这个想法是,您不是“等待”5 秒,而是反转控制,让计时器调用您的工作。
这不好:
protected override void OnStart(string[] args)
{
while (true)
{
RunScheduledTasks(); // This is your "work"
Thread.Sleep(5000);
}
}
这很好:
public class MyService : ServiceBase
{
private Timer workTimer; // System.Threading.Timer
protected override void OnStart(string[] args)
{
workTimer = new Timer(new TimerCallback(DoWork), null, 5000, 5000);
base.OnStart(args);
}
protected override void OnStop()
{
workTimer.Dispose();
base.OnStop();
}
private void DoWork(object state)
{
RunScheduledTasks(); // Do some work
}
}
就是这样。这就是您定期工作所需要做的全部工作。只要工作本身一次不运行几秒钟,您的服务就会保持对服务控制器的响应。在这种情况下你甚至可以支持暂停:
protected override void OnPause()
{
workTimer.Change(Timeout.Infinite, Timeout.Infinite);
base.OnPause();
}
protected override void OnContinue()
{
workTimer.Change(0, 5000);
base.OnContinue();
}
您需要开始在服务中创建工作线程的唯一时间是当工作本身可以运行很长时间并且您需要能够在中间取消时。这往往涉及大量的设计工作,因此在不确定它与您的场景相关的情况下,我不会深入讨论它。
除非您确实需要,否则最好不要开始将多线程语义引入到您的服务中。如果您只是想安排要完成的小型工作单元,那么您绝对不需要它。