.net 如何正确停止单线程windows服务(桌面)?

.net 如何正确停止单线程windows服务(桌面)?,.net,windows-services,manualresetevent,single-threaded,.net,Windows Services,Manualresetevent,Single Threaded,我有一个用VS 2010/.NET 4.0编写的windows服务 该服务遵循以下代码片段的方案:使用计时器,每隔几分钟执行一次所需的行为。每几分钟执行一次的“期望行为”的要求现在已经发展成大约需要10秒的工作 我只需要该服务中的一个线程,没有理由创建多个线程,这就是为什么我将windows服务称为单线程 我担心的是,如果有人通过管理控制台停止服务,可能只是在服务偶尔进行的10秒钟工作期间 我已经读了一些关于SO和如何停止服务的书,但是我有点不知所措。有时会创建WorkerThreads,有时会

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

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

我只需要该服务中的一个线程,没有理由创建多个线程,这就是为什么我将windows服务称为单线程

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

我已经读了一些关于SO和如何停止服务的书,但是我有点不知所措。有时会创建WorkerThreads,有时会创建ManualResetEvents,但到目前为止,我还不能完全掌握windows服务的最佳前进方向

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

理论到此为止;),但考虑到下面的代码片段,我最好的前进方向是什么

谢谢大家

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

只需锁定,使OnStop()不能与已用事件处理程序同时运行:

   Protected Overrides Sub OnStop()
       SyncLock Me
           _timer.Stop()
       End SyncLock
   End Sub
如果可以进行竞争,则已用事件处理程序可能已计划运行,但尚未进入锁。因此,请确认计时器仍处于启用状态:

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

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

只需锁定,使OnStop()不能与已用事件处理程序同时运行:

   Protected Overrides Sub OnStop()
       SyncLock Me
           _timer.Stop()
       End SyncLock
   End Sub
如果可以进行竞争,则已用事件处理程序可能已计划运行,但尚未进入锁。因此,请确认计时器仍处于启用状态:

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

喜欢一个专用的锁对象而不是我。注意服务控制员在放弃之前愿意等待的30秒,您离我们越来越近了。

Hans,非常感谢您的回复。由于我不太习惯于比赛条件:在_timer\u appeased方法中,对“If not _timer.Enabled Return”的检查不应该在“SyncLock Me”之前吗?我认为(正如您所说)如果运行的事件处理程序可能已经计划运行,但尚未进入锁,那么它应该在尝试获取锁之前检查计时器是否仍然处于启用状态,即没有调用stop。否则就不能造成僵局吗?再次感谢。不,它必须在后面,如代码片段所示。你不能从返回语句中获得死锁。汉斯,非常感谢你的回复。由于我不太习惯于比赛条件:在_timer\u appeased方法中,对“If not _timer.Enabled Return”的检查不应该在“SyncLock Me”之前吗?我认为(正如您所说)如果运行的事件处理程序可能已经计划运行,但尚未进入锁,那么它应该在尝试获取锁之前检查计时器是否仍然处于启用状态,即没有调用stop。否则就不能造成僵局吗?再次感谢。不,它必须在后面,如代码片段所示。您无法从Return语句中获得死锁。