public IOThreadTimer(Action<object> callback, object callbackState, bool isTypicallyCanceledShortlyAfterBeingSet, int maxSkewInMilliseconds) { this.callback = callback; this.callbackState = callbackState; this.maxSkew = Ticks.FromMilliseconds(maxSkewInMilliseconds); this.timerGroup = isTypicallyCanceledShortlyAfterBeingSet ? TimerManager.Value.VolatileTimerGroup : TimerManager.Value.StableTimerGroup; }
public void Reload() { list = new System.Collections.Specialized.HybridDictionary(); System.Xml.XmlDocument x = new System.Xml.XmlDocument(); if (!File.Exists(GetPathName())) { return; //Nothing to load } x.Load(GetPathName()); foreach (System.Xml.XmlNode node in x.SelectNodes("//Timer")) { if (node.Attributes["name"] == null) { continue; } string name = node.Attributes["name"].Value; if (name == null) { continue; } Timer timer = Create(name); foreach (System.Xml.XmlNode lap in node.SelectNodes("lap")) { string startText = (lap.Attributes["start"] != null) ? lap.Attributes["start"].Value : null; DateTime start = DateTime.Parse(startText, GetCulture()); string task = (lap.Attributes["task"] != null) ? lap.Attributes["task"].Value : null; if (lap.Attributes["end"] == null) { timer.AddFluent(start, task); } else { string endText = lap.Attributes["end"].Value; DateTime end = DateTime.Parse(endText, GetCulture()); timer.AddFluent(start, end, task); } } } foreach (System.Xml.XmlNode node in x.SelectNodes("//Group")) { Groups.Add(TimerGroup.Parse(node, this)); } }
private static void UpdateWaitableTimer(TimerGroup timerGroup) { WaitableTimer waitableTimer = timerGroup.WaitableTimer; IOThreadTimer minTimer = timerGroup.TimerQueue.MinTimer; long timeDiff = waitableTimer.DueTime - minTimer._dueTime; if (timeDiff < 0) { timeDiff = -timeDiff; } if (timeDiff > minTimer._maxSkew) { waitableTimer.Set(minTimer._dueTime); } }
private void ReactivateWaitableTimer(TimerGroup timerGroup) { TimerQueue timerQueue = timerGroup.TimerQueue; if (timerGroup.WaitableTimer.dead) { return; } if (timerQueue.Count > 0) { timerGroup.WaitableTimer.Set(timerQueue.MinTimer.dueTime); } else { timerGroup.WaitableTimer.Set(long.MaxValue); } }
static void ScheduleElapsedTimers(TimerGroup timerGroup, long now) { TimerQueue timerQueue = timerGroup.TimerQueue; while (timerQueue.Count > 0) { IOThreadTimer timer = timerQueue.MinTimer; long timeDiff = timer.dueTime - now; if (timeDiff <= timer.maxSkew) { timerQueue.DeleteMinTimer(); ActionItem.Schedule(timer.callback, timer.callbackState); } else { break; } } }
public void ShouldScheduleActionOnIntervalAfterAdd() { VirtualClock clock = new VirtualClock(); using (TimerGroup timers = new TimerGroup() { Create = clock.CreateAction }) { int invokeCount = 0; timers.Add(TimeSpan.FromSeconds(1.0d), () => ++ invokeCount); Assert.AreEqual(0, invokeCount); clock.Sleep(TimeSpan.FromSeconds(1.1d)); Assert.AreEqual(1, invokeCount); } }
public bool Cancel(IOThreadTimer timer) { lock (ThisLock) { if (timer.index > 0) { TimerGroup timerGroup = timer.timerGroup; TimerQueue timerQueue = timerGroup.TimerQueue; timerQueue.DeleteTimer(timer); if (timerQueue.Count > 0) { UpdateWaitableTimer(timerGroup); } else { TimerGroup otherTimerGroup = GetOtherTimerGroup(timerGroup); if (otherTimerGroup.TimerQueue.Count == 0) { long now = Ticks.Now; long thisGroupRemainingTime = timerGroup.WaitableTimer.DueTime - now; long otherGroupRemainingTime = otherTimerGroup.WaitableTimer.DueTime - now; if (thisGroupRemainingTime > maxTimeToWaitForMoreTimers && otherGroupRemainingTime > maxTimeToWaitForMoreTimers) { timerGroup.WaitableTimer.Set(Ticks.Add(now, maxTimeToWaitForMoreTimers)); } } } return(true); } else { return(false); } } }
public void Set(IOThreadTimer timer, long dueTime) { long timeDiff = dueTime - timer.dueTime; if (timeDiff < 0) { timeDiff = -timeDiff; } if (timeDiff > timer.maxSkew) { lock (ThisLock) { TimerGroup timerGroup = timer.timerGroup; TimerQueue timerQueue = timerGroup.TimerQueue; if (timer.index > 0) { if (timerQueue.UpdateTimer(timer, dueTime)) { UpdateWaitableTimer(timerGroup); } } else { if (timerQueue.InsertTimer(timer, dueTime)) { UpdateWaitableTimer(timerGroup); if (timerQueue.Count == 1) { EnsureWaitScheduled(); } } } } } }
public void ShouldCancelActionByIdAfterRemove() { VirtualClock clock = new VirtualClock(); using (TimerGroup timers = new TimerGroup() { Create = clock.CreateAction }) { int invokeCount1 = 0; int invokeCount2 = 0; Guid id1 = timers.Add(TimeSpan.FromSeconds(1.0d), () => ++ invokeCount1); Guid id2 = timers.Add(TimeSpan.FromSeconds(1.5d), () => ++ invokeCount2); Assert.AreNotEqual(id1, id2); Assert.AreEqual(0, invokeCount1); Assert.AreEqual(0, invokeCount2); clock.Sleep(TimeSpan.FromSeconds(1.1d)); Assert.AreEqual(1, invokeCount1); Assert.AreEqual(0, invokeCount2); clock.Sleep(TimeSpan.FromSeconds(1.0d)); Assert.AreEqual(2, invokeCount1); Assert.AreEqual(1, invokeCount2); timers.Remove(id1); clock.Sleep(TimeSpan.FromSeconds(1.0d)); Assert.AreEqual(2, invokeCount1); Assert.AreEqual(2, invokeCount2); } }
TimerGroup GetOtherTimerGroup(TimerGroup timerGroup) { if (object.ReferenceEquals(timerGroup, this.volatileTimerGroup)) { return this.stableTimerGroup; } else { return this.volatileTimerGroup; } }
static void UpdateWaitableTimer(TimerGroup timerGroup) { WaitableTimer waitableTimer = timerGroup.WaitableTimer; IOThreadTimer minTimer = timerGroup.TimerQueue.MinTimer; long timeDiff = waitableTimer.DueTime - minTimer.dueTime; if (timeDiff < 0) { timeDiff = -timeDiff; } if (timeDiff > minTimer.maxSkew) { waitableTimer.Set(minTimer.dueTime); } }
static void ScheduleElapsedTimers(TimerGroup timerGroup, long now) { TimerQueue timerQueue = timerGroup.TimerQueue; while (timerQueue.Count > 0) { IOThreadTimer timer = timerQueue.MinTimer; long timeDiff = timer.dueTime - now; if (timeDiff <= timer.maxSkew) { timerQueue.DeleteMinTimer(); IOThreadScheduler.ScheduleCallbackNoFlow(timer.callback, timer.callbackState); } else { break; } } }
static void ReactivateWaitableTimer(TimerGroup timerGroup) { TimerQueue timerQueue = timerGroup.TimerQueue; if (timerQueue.Count > 0) { timerGroup.WaitableTimer.Set(timerQueue.MinTimer.dueTime); } else { timerGroup.WaitableTimer.Set(long.MaxValue); } }
public TimerManager() { this.onWaitCallback = new Action<object>(OnWaitCallback); this.stableTimerGroup = new TimerGroup(); this.volatileTimerGroup = new TimerGroup(); this.waitableTimers = new WaitableTimer[] { this.stableTimerGroup.WaitableTimer, this.volatileTimerGroup.WaitableTimer }; }
private TimerGroup GetOtherTimerGroup(TimerGroup timerGroup) { return(ReferenceEquals(timerGroup, VolatileTimerGroup) ? StableTimerGroup : VolatileTimerGroup); }