protected void Callback(DateTime now) { var boundary = TimerCall.At(now); SortedSet <TimerCall> toCall; // get all calls scheduler before infinity and now remove // them once from the set of awaiting calls then try to // advance them and scheduler for a next call lock (syncLock) { toCall = this.calls.GetViewBetween(TimerCall.Min, boundary); this.calls.ExceptWith(toCall); foreach (var call in toCall) { if (call.TryAdvance()) { this.calls.Add(call); } } } foreach (var call in toCall) { try { call.Call(); } catch (Exception cause) { var failure = new TimerFailure(now, cause, call.Call); this.OnError?.Invoke(this, failure); } } }
private IDisposable Schedule(Action action, TimeSpan delay, TimeSpan?interval = null) { if (disposed) { throw new ObjectDisposedException("Timer has been disposed"); } var timerCall = new TimerCall(action, DateTime.UtcNow + delay, interval); lock (syncLock) { this.calls.Add(timerCall); } return(new TimerDisposer(this, timerCall)); }
public TimerDisposer(AbstractTimer timer, TimerCall call) { this.timer = timer; this.call = call; }