2009-06-15 12 views
12

私は、長時間スリープする必要のあるWindowsサービスを作成しています(15時間は最長です.30分が最短です)。私は現在、Thread.Sleep(calculatedTime)を使用してコードをスリープモードにしています。 Thread.Sleepが最善の選択ですか、それともタイマーを使用すべきですか?私はしばらくの間これをグーグルで探していて、簡潔な答えを見つけることができません。これはWindowsサービスなので、UIのロックについて心配する必要はないので、Thread.Sleepを使用しない理由は考えられません。WindowsサービスでThread.Sleep()を使用する

洞察力があれば幸いです。

答えて

19

私はタイマーThread.Sleepを使用して、サービスのシャットダウンを妨げるブロッキングピースを引き起こす可能性があります。

間隔が広がり、定期的な場合は、その間隔もスケジュールするだけです。しかし、長くて一定しない間隔について話しているのなら、タイマーが良いでしょう。

7

多くの場合、Thread.Sleep()を使用することは一般に悪い習慣とみなされます。

サービスをバックグラウンドで実行する場合は、タイマーを使用する必要があります。

サービスが定期的に実行される必要がある場合は、Windowsタスクスケジューラを使用して、必要なときにWindowsがアプリケーションを実行できるようにすることをおすすめします。

5

このような大量の時間をあらかじめ計算しておけば、何時間も眠るべきではありません。最高で1分間眠ってから、目を覚まして時間を再計算し、もう一度眠ります。私は計算が非常に安いか、キャッシュで非常に安くすることができると思います。私のアドバイスが軽減しようとしている問題は、コンピュータ時計が昼間の節約のために、またユーザーが時計を調整していることが理由で、ネットワークタイムサービスによって修正された時間ドリフトのために、たとえ1分ごとに目を覚ますことを意味していたとしても、そのような長い間隔の時間を絶えず再計算する方が良いです。そして、あなたが「過去」に目を覚ますと、驚かされないでください(つまり、アサートしないでください)。

1

さらに、スレッドは有限のリソースであり、各スレッドはそのスタックに対してメモリの一部(1MB?)を消費することに注意してください。また、スケジューラの負荷も増加する可能性があります。

サービスがあまり進まない場合は、無駄なスペースはほとんどありませんが、複数のスレッドの割り当てを開始する前に、このことに注意することをお勧めします。 ThreadPoolやTimerを使う方がはるかに効率的です。

9

Service Control Managerによってサービスがいつでも停止するように要求されることがあるため、スレッドは常にこれらの要求に応答する準備ができている必要があります。したがって、Thread.Sleep()を使用しないでください。代わりに、メインスレッドで手動リセットイベントを作成し、WaitOneメソッドをワーカースレッドのタイムアウトとともに使用します。 WaitOneは時間が経過するとfalseを返します。

サービスクラスのOnStopまたはOnShutdownメソッドが呼び出されると、イベントを設定すると、WaitOneがtrueを返し、ワーカースレッドを終了できます。

関連する問題