web-dev-qa-db-ja.com

C#タイマーまたはThread.Sleep

私はWindowsサービスを実行しており、ループとThread.Sleepを使用してタスクを繰り返していますが、タイマーメソッドを使用する方が良いでしょうか?

はいの場合、コード例は素晴らしいでしょう

私は現在、このコードを使用して繰り返しています

int curMinute;
int lastMinute = DateTime.Now.AddMinutes(-1).Minute;

while (condition)
{
   curMinute = DateTime.Now.Minute;

   if (lastMinute < curMinute) {
         // do your once-per-minute code here
         lastMinute = curMinute;
   }

   Thread.Sleep(50000);      // sleeps for 50 seconds

   if (error condition that would break you out of this) {
       break;      // leaves looping structure
   }
}
45
Adonis L
class Program
{
    static void Main(string[] args)
    {
        Timer timer = new Timer(new TimerCallback(TimeCallBack),null,1000,50000);
        Console.Read();
        timer.Dispose();
    }

    public static void TimeCallBack(object o)
    {
      curMinute = DateTime.Now.Minute;
      if (lastMinute < curMinute) {
       // do your once-per-minute code here
       lastMinute = curMinute;
    }
}

コードは上記のようなものになります

32
Prashanth

タイマーはより良いアイデアです、IMO。そうすれば、サービスを停止するように要求された場合、非常に迅速に応答でき、タイマーティックハンドラーを再度呼び出すだけではありません...スリープしている場合、サービスマネージャーは50秒待機するか、どちらもひどくニースではありません。

43
Jon Skeet

コードが1つのループを終了してから次のループを開始するまで50秒間スリープすることを理解することが重要です...

タイマーは50秒ごとにループを呼び出しますが、これはまったく同じではありません。

どちらも有効ですが、タイマーはおそらくここで探しているものです。

11

Sleep()を呼び出すとサービスがフリーズするため、サービスの停止が要求された場合、Sleep()コールの期間中は反応しません。

7

はい、タイマーを使用すると、現在ほとんどの時間をスリープ状態にしているスレッドが解放されます。また、タイマーは毎分より正確に起動するため、lastMinuteを追跡する必要はおそらくないでしょう。

4
Jon Norton

質問にまったく答えていませんが、むしろ

   if (error condition that would break you out of this) {
       break;      // leaves looping structure
   }

あなたはおそらく持っている必要があります

while(!error condition)

また、Timerを使用します。

2
cjk

状況に応じて、タイマーとThread.Sleep(x)の両方を使用しました。

繰り返し実行する必要のある短いコードがある場合は、おそらくタイマーを使用します。

遅延タイマーよりも実行に時間がかかる可能性のあるコードがある場合(FTP経由でリモートサーバーからファイルを取得する場合など、ネットワーク遅延やファイルサイズ/カウントを制御したり、知らなかったりする場合)、待機しますサイクル間の一定期間。

どちらも有効ですが、前に指摘したように、それらは異なることを行います。前のインスタンスが終了していなくても、タイマーはコードをxミリ秒ごとに実行します。 Thread.Sleep(x)は、各反復の完了後、一定期間待機するため、ループごとの合計遅延は常にスリープ期間よりも長くなります(おそらくそれほど長くはありません)。

1
jwhitley

毎分1回スレッドを起動する必要があり( ここの質問を参照 )、受け取った回答に基づいて DispatchTimer を使用しました。

答えは、あなたが役に立つと思うかもしれないいくつかの参照を提供します。

1
Simon Temlett

私も同意します、タイマーを使用することが最良の選択肢です。私は過去にあなたに似た解決策を試みましたが、ループが不発になる問題を抱え始めました。そして、再び発火する前に別のThread.Sleep()を待たなければなりません。また、それはサービスを停止することに関するあらゆる種類の問題を引き起こしました、私はそれがどのように応答しなかったか、そして閉じられなければならなかったかについて絶え間ないエラーを得るでしょう。

@Prashanthのコードは、まさにあなたが必要とするものでなければなりません。

0
Nick DeMayo

どちらでも使用できます。しかし、Sleep()は実装が簡単で、明確で、短いと思います。

0
Umair Ahmed