/// <summary> /// Resolve Pending Timer to be Inserted in Scheduler /// </summary> private void ResolvePendingTimers() { while (!PendingTimers.IsEmpty) { Tuple <long, ScheduledTask> task; if (PendingTimers.TryTake(out task)) { List <ScheduledTask> scheduled; if (!ScheduledTimers.TryGetValue(task.Item1, out scheduled)) { scheduled = new List <ScheduledTask>(); ScheduledTimers.Add(task.Item1, scheduled); } scheduled.Add(task.Item2); } } }
/// <summary> /// Start All Tasks /// </summary> private void ConsumePendingScheduledTasks() { var StartedTicksIndex = new List <long>(); foreach (KeyValuePair <long, List <ScheduledTask> > tasks in ScheduledTimers.Where(ent => ent.Key <= Ticks)) { StartedTicksIndex.Add(tasks.Key); foreach (ScheduledTask taskEntry in tasks.Value) { // scope copy for thread safety var timerTask = taskEntry; var task = Task.Factory.StartNew(() => LaunchScheduledTask(timerTask)); RunningTimers.Add(new Tuple <long, Task>(Ticks, task)); } } foreach (var key in StartedTicksIndex) { ScheduledTimers.Remove(key); } }
/// <summary> /// Timer Event Starting All Due Tasks /// </summary> /// <param name="source"></param> /// <param name="e"></param> private void OnTick(object source, ElapsedEventArgs e) { System.Threading.Interlocked.Exchange(ref NextDueTick, long.MaxValue); var nextDueTime = long.MaxValue; lock (SchedulerLock) { ResolveRunningTimers(); ResolvePendingTimers(); ConsumePendingScheduledTasks(); // Schedule Next Tick var nextTask = ScheduledTimers.FirstOrDefault(); if (nextTask.Value != null) { nextDueTime = nextTask.Key; } } SignalNextDueTick(nextDueTime); }