1

VS 2010 /.NET4.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
4

1 に答える 1

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秒間気をつけてください、あなたは近づいています。

于 2012-11-19T20:30:22.723 に答える