.net - 线程 sleep 和Windows服务

标签 .net multithreading windows-services timer sleep

我正在使用Windows服务,但Thread.Sleep()出现了一些问题,因此我认为我会尝试使用计时器代替此问题,因为它建议:

Using Thread.Sleep() in a Windows Service

我还不清楚如何实现这一目标。我相信这是方法,但我只是想确保:

'' Inside The Service Object
Dim closingGate As System.Threading.AutoResetEvent

Protected Overrides Sub OnStart(ByVal args() As String)
   Dim worker As New Threading.Thread(AddressOf Work)
   worker.Start()
End Sub

Protected Sub Work()
   Dim Program = New MyProgram()
   closingGate = New System.Threading.AutoResetEvent(False)
   Program.RunService(closingGate)
End Sub

Protected Overrides Sub OnStop()
   closingGate.Set()
End Sub

'' Inside My Programs Code:
Public Sub RunService(closingGate As AutoResetEvent)
   Dim tmr As New Timer
   '' ...and so on

   closingGate.WaitOne()
End Sub

除了使用VB.Net(打结,但如果可以的话,我会使用C#。)我是否在这里正确?这比使用Thread.Sleep()好吗?

最佳答案

老实说,我不得不说,我认为您在这里已经远离人迹罕至的地方了。

首先,实际发布的代码没有任何意义。工作线程正在等待信号,但没有任何原因-实际上,它不在任何形式的循环中或在等待资源。其次,如果在收到关闭信号后确实需要在工作线程中执行一些(也许省略了)清理代码,则您的服务可能没有给工作线程足够的时间进行清理。

但是,更根本地讲,您要做的就是将问题转移到单独的线程中。这可能会使服务对服务 Controller 保持响应,但不能解决设计问题-并通过使用线程和互斥锁增加了很多不必要的复杂性。最终,如果需要的话,这只会使您的服务难以调试。

假设您需要每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
    }
}

就是这样。这就是您需要定期进行的所有工作。只要工作本身一次没有运行几秒钟,您的服务就会对服务 Controller 保持响应。在这种情况下,您甚至可以支持暂停:
protected override void OnPause()
{
    workTimer.Change(Timeout.Infinite, Timeout.Infinite);
    base.OnPause();
}

protected override void OnContinue()
{
    workTimer.Change(0, 5000);
    base.OnContinue();
}

唯一需要开始在服务中创建工作线程的时间是工作本身可以运行很长时间并且您需要在中间取消的能力。这往往涉及大量的设计工作,因此在不确定它是否与您的方案有关的情况下,我将不予讨论。

除非确实需要,否则最好不要开始在服务中引入多线程语义。如果您只是想安排要完成的小型工作单元,则绝对不需要。

关于.net - 线程 sleep 和Windows服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2405619/

相关文章:

c# - 线程池 + 轮询 C# .Net 3.5

windows - 为什么我可以在运行时重命名 Windows 服务可执行文件?

c# - 事件处理程序会阻止垃圾收集的发生吗?

c# - Unity 容器 - 延迟注入(inject)

Java 内部和显式全局锁定的等效性

java - 访问并发集合的同步语法

.net - ObjectContext.SaveChanges() 因 SQL CE 失败

c# - 这些虚拟表有什么意义?

java - 快速写入 JEditorPane

c# - Windows 服务是否可以在没有密码的情况下模拟用户?