public AgeUpdatingService(IEnumerable <IBirthday> participants, IDispatcherTimer timer, int capacity = 4) { _timer = timer; _timer.Tick += OnTick; _participants = new OrderedList <KeyValuePair <TimeSpan, IBirthday> >(capacity, new KeyComparer <TimeSpan, IBirthday>()); _participants.AddRange(participants.Select(p => new KeyValuePair <TimeSpan, IBirthday>(p.DateTimeBirth.TimeOfDay, p))); if (_participants.Any()) { TimeSpan nowTime = DateTime.Now.TimeOfDay; _nextIndex = _participants.BinarySearch(new KeyValuePair <TimeSpan, IBirthday>(nowTime, null)); if (_nextIndex < 0) { _nextIndex = ~_nextIndex; } TimeSpan interval; if (_nextIndex >= _participants.Count) { _nextIndex = 0; interval = TimeSpan.FromDays(1) - nowTime + _participants[0].Key; } else { interval = _participants[_nextIndex].Key - nowTime; } StartTimer(interval); } }
public void TestIntegerList() { var startList = new List <int>(new int[] { 5, 2, 1, 4, 5, 5, 2 }); var olist = new OrderedList <int>(startList); startList = startList.OrderBy(l => l).ToList(); CollectionAssert.AreEqual(startList, olist); Assert.AreEqual(0, olist.Add(0)); int nextInc = olist.Max() + 1; Assert.AreEqual(olist.Count, olist.Add(nextInc)); CollectionAssert.AreEqual(startList.Concat(new int[] { 0, nextInc }).OrderBy(l => l).ToList(), olist); Assert.IsTrue(olist.Remove(0)); Assert.IsFalse(olist.Remove(0)); Assert.IsTrue(olist.Remove(nextInc)); CollectionAssert.AreEqual(startList, olist); var addList = new List <int>(new int[] { 5, -1, 2, 2, -1, 3, 2 }); olist.AddRange(addList); addList = startList.Concat(addList).OrderBy(l => l).ToList(); CollectionAssert.AreEqual(addList, olist); olist.Remove(-1); addList.Remove(-1); CollectionAssert.AreEqual(addList, olist); olist.Remove(2); addList.Remove(2); CollectionAssert.AreEqual(addList, olist); olist = new OrderedList <int>(); int[] seed = new int[] { -2, -2 }; olist.AddRange(seed); CollectionAssert.AreEqual(seed, olist); olist.AddRange(new int[] { }); olist.AddRange(new int[] { -2 }); CollectionAssert.AreEqual(seed.Concat(new int[] { -2 }).ToList(), olist); olist.AddRange(new int[] { -3 }); CollectionAssert.AreEqual((new int[] { -3, -2 }).Concat(seed).ToList(), olist); }
private bool TryProcessPage(ContentObject page, IEnumerable <IContentProcessor> pageProcessors, OrderedList <IContentProcessor> pendingPageProcessors, bool copyOutput) { // If page is discarded, skip it if (page.Discard) { return(false); } // By default working on all processors // Order is important! pendingPageProcessors.AddRange(pageProcessors); bool hasBeenProcessed = true; bool breakProcessing = false; // We process the page going through all IContentProcessor from the end of the list // (more priority) to the beginning of the list (less priority). // An IContentProcessor can transform the page to another type of content // that could then be processed by another IContentProcessor // But we make sure that a processor cannot process a page more than one time // to avoid an infinite loop var clock = Stopwatch.StartNew(); while (hasBeenProcessed && !breakProcessing && !page.Discard) { hasBeenProcessed = false; for (int i = pendingPageProcessors.Count - 1; i >= 0; i--) { var processor = pendingPageProcessors[i]; // Note that page.ContentType can be changed by a processor // while processing a page clock.Restart(); try { var result = processor.TryProcess(page); if (result != ContentResult.None) { // Update statistics per plugin var statistics = Site.Statistics; var stat = statistics.GetPluginStat(processor); stat.PageCount++; stat.ContentProcessTime += clock.Elapsed; hasBeenProcessed = true; pendingPageProcessors.RemoveAt(i); breakProcessing = result == ContentResult.Break; break; } } catch (Exception ex) { Site.Error(ex, $"Error while processing {page.Path}."); breakProcessing = true; hasBeenProcessed = true; break; } } } pendingPageProcessors.Clear(); // Copy only if the file are marked as include if (copyOutput && !breakProcessing && !page.Discard) { Site.Content.TryCopyContentToOutput(page, page.GetDestinationPath()); } return(true); }