5

15 分ごとなど、定期的にキューを処理する Windows サービス (.NET 4) があります。System.Threading.Timerサービスが X ミリ秒ごとにコールバックを開始するときに設定されるを使用します。通常、各実行には数秒かかり、衝突することはありませんが、それを想定できない場合はどうなりますか?処理が進行中の場合は、次の実行をすぐに終了させます。

これは、ロック、揮発性ブール、またはモニターで簡単に解決できますが、実際にこのシナリオで使用するのに適切なもの、または単に一般的に推奨されるオプションは何ですか?

ほとんどこのシナリオ ( Volatile vs. Interlocked vs. lockなど) に答える他の投稿を見つけましたが、これを Timer の例に拡張してすぐに終了するためのアドバイスが必要です。

4

3 に答える 3

6

これにはロックは必要ありません。タイマーデリゲート内から次のタイマーの実行を再スケジュールするだけです。これにより、100% オーバーラップがないことが保証されます。

タイマーのイベント ハンドラー呼び出しの終了時にtimer.Change(nextRunInMilliseconds, Timeout.Infinite)、タイマーはnextRunInMilliseconds.

例:

//Object that holds timer state, and possible additional data
private class TimerState
{
    public Timer Timer { get; set; }
    public bool Stop { get; set; }
}

public void Run()
{
    var timerState = new TimerState();
    //Create the timer but don't start it
    timerState.Timer = new Timer(OnTimer, timerState, Timeout.Infinite, Timeout.Infinite);
    //Start the timer
    timerState.Timer.Change(1000, Timeout.Infinite);
}

public void OnTimer(object state)
{
    var timerState = (TimerState) state;            
    try
    {
        //Do work
    }
    finally 
    {
        //Reschedule timer
        if (!timerState.Stop)
            timerState.Timer.Change(1000, Timeout.Infinite);
    }
}
于 2013-06-24T09:10:18.603 に答える