2012-11-19 5 views
1

VS 2010/.NET 4.0으로 작성된 Windows 서비스가 있습니다.단일 스레드 Windows 서비스 (onStop)를 올바르게 중지하는 방법은 무엇입니까?

서비스는 아래의 코드 스 니펫을 따르고 있습니다. 타이머를 사용하여 몇 분마다 원하는 동작을 실행합니다. 2 분마다 실행되는 "원하는 동작"에 대한 요구 사항은 이제 약 10 초가 걸리는 작업으로 커졌습니다.

그 서비스에 하나의 스레드 만 있으면 여러 스레드를 만들 이유가 없습니다. 그래서 Windows 서비스를 단일 스레드라고합니다.

내가 걱정하는 것은 누군가가 관리 콘솔을 통해 서비스를 중지하면 서비스가 때때로 수행되는 10 초 동안 일 수 있다는 것입니다.

나는 SO에서 약간의 독서를했으며 서비스를 중단하는 방법을 알고 있지만 약간은 분실했다. 때로는 WorkerThread가 만들어 지기도하지만 때로는 ManualResetEvent가 만들어 지지만 지금까지는 내 Windows 서비스를위한 최선의 방법을 완전히 파악할 수 없었습니다.

나는 10 초 동안 어떤 종류의 깃발을 조사하고 그 깃발이 멈춰야한다는 것을 말하지 않으면 계속할 필요가 있다고 생각하고있다. 그리고 onStop 메서드에서 처리가 제대로 끝날 때까지 기다려야 할 것입니다.

너무 많은 이론에 대한)하지만, 앞으로 최선의 방법은 무엇입니까, 아래의 코드 스 니펫을 고려?

감사합니다. 를 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 

답변

1

그냥 잠금을 :

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

, 경과 이벤트 처리기가 이미 실행하도록 예약 그러나 didn를 할 수있는 경주 수있는 아직 자물쇠를 열지 마라. 타이머가 여전히 활성화되어 있는지 확인하십시오.

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

Me 대신 전용 잠금 개체가 있습니다. 그리고 서비스 컨트롤러가 포기하기 전에 기다려야하는 30 초를 조심하십시오. 가까이오고 있습니다.

+0

한스, 귀하의 회신에 많은 감사드립니다. 조건 경쟁에 익숙하지 않기 때문에 : _timer_Elapsed 메소드의 "SyncLock Me"앞에 "If Not _timer.Enabled Return"이 표시되어 있어야합니까? Elapsed 이벤트 핸들러가 이미 실행되도록 예약되었지만 아직 잠금을 입력하지 않았다면 (당신이 말한 것처럼) 타이머가 여전히 활성화되어있는 잠금을 획득하기 전에 확인해야합니다. 즉 정지하지 않습니다 ' t라고 불렀다. 그렇지 않으면 교착 상태가 발생할 수 있습니까? 다시 한번 감사드립니다. – ManOnAMission

+0

아니요, 스 니펫에 표시된대로 이후 여야합니다. Return 문에서 교착 상태를 얻을 수 없습니다. –

+0

감사합니다. Hans, 지금 당장! – ManOnAMission