これにはロックは必要ありません。タイマーデリゲート内から次のタイマーの実行を再スケジュールするだけです。これにより、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);
}
}