【问题标题】:How to properly stop single threaded windows service (onStop)?如何正确停止单线程 Windows 服务(onStop)?
【发布时间】:2012-11-07 18:27:10
【问题描述】:

我有一个用 VS 2010 / .NET 4.0 编写的 Windows 服务。

该服务遵循以下代码 sn-p 的方案:使用计时器,它每几分钟执行一些所需的行为。每隔几分钟执行一次“期望行为”的要求现在已经发展为大约需要 10 秒的工作。

我在那个服务中只需要一个线程,没有理由创建多个线程,这就是我将 windows 服务称为单线程的原因。

我担心的是,如果有人通过管理控制台停止服务,可能只是在服务偶尔执行的 10 秒工作期间。

我已经阅读了一些关于 SO 以及如何停止服务的内容,但有点迷茫。有时会创建 WorkerThreads,有时会创建 ManualResetEvents,但到目前为止,我还无法完全掌握 Windows 服务的最佳前进方向。

我认为我需要在 10 秒执行期间检查某种标志,然后仅在该标志没有告诉我应该停止时才继续。在 onStop 方法中,我可能需要等到处理正确完成。

理论讲了这么多;),但是考虑到下面的代码 sn-p,我最好的前进方式是什么?

谢谢大家!

Public Class MyService
   Public _timer As System.Timers.Timer

   Protected Overrides Sub OnStart(ByVal args() As String)
       _timer = New System.Timers.Timer()
       'more timer settings
       AddHandler _timer.Elapsed, AddressOf _timer_Tick
       _timer.Start()
   End Sub

   Protected Overrides Sub OnStop()
   ' ????????????????????????
   End Sub

   Private Sub _timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
       SyncLock Me
           try
              _timer.Stop()
           catch ex as Exception            
           finally
              _timer.Start()
           end try
       End SyncLock
   End Sub
End Class

【问题讨论】:

    标签: .net windows-services manualresetevent single-threaded


    【解决方案1】:

    只需锁定,这样 OnStop() 就不能与 Elapsed 事件处理程序同时运行:

       Protected Overrides Sub OnStop()
           SyncLock Me
               _timer.Stop()
           End SyncLock
       End Sub
    

    哪个可以竞争,Elapsed 事件处理程序可能已经计划运行但尚未进入锁定。所以验证计时器是否仍然启用:

       Private Sub _timer_Elapsed(ByVal sender As Object, ByVal e As EventArgs)
           SyncLock Me
               If Not _timer.Enabled Return
               '' etc..
    

    喜欢一个专用的锁对象而不是我。并注意服务控制器愿意在放弃前等待的 30 秒,您已经接近了。

    【讨论】:

    • 汉斯,非常感谢您的回复。因为我不习惯竞争条件:不应该在 _timer_Elapsed 方法中的“SyncLock Me”之前检查“If Not _timer.Enabled Return”吗?我在想(如你所说)如果 Elapsed 事件处理程序可能已经被安排运行但尚未进入锁,那么它应该在尝试获取锁之前检查计时器是否仍然启用,即停止没有没有被叫。否则不会导致死锁吗?再次感谢。
    • 不行,必须是after,如sn -p所示。您不能从 Return 语句中获得死锁。
    猜你喜欢
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多