//private static FuturedTask SearchTask = new FuturedTask(null, default(DateTime)); static TickManager() { for (int i = 0; i < NumberOfSets; i++) { TickSets[i] = new MovingConcurrentSet(); TickSets[i].scheduleOffset = i; } StartOffset = DateTime.UtcNow.Ticks; }
private static void RunTickManager() { NextWakeup = DateTime.UtcNow; int nextSet = 0; while (!Program.ShutdownTrigger.WaitOne(0)) { DateTime currentTime = DateTime.UtcNow; FuturedTask nextTask; while (ImmediateTickSet.TryTake(out nextTask)) { RunOrQueue(nextTask); } nextTask = null; while (!ThreadManager.MUDIsPaused && TasksToRunSoon.Count > 0) { nextTask = TasksToRunSoon[0]; if (nextTask.scheduledTime > currentTime + new TimeSpan(0, 0, 0, 0, NowLimit)) { break; } TasksToRunSoon.RemoveAt(0); if (nextTask.IsCanceled()) { continue; } ThreadPool.QueueUserWorkItem(RunTask, nextTask); } //Floor of division, but +1. Gets all the sets that might have things to run right now. long rawSetIndex = 1 + ((currentTime.Ticks - StartOffset) / TimeSpan.TicksPerMillisecond / MillisecondsPerSet); int setIndex = (int)rawSetIndex; //int setToAddTo = setIndex % NumberOfSets; while (setIndex > nextSet) { MovingConcurrentSet setToSwitch = TickSets[nextSet % NumberOfSets]; setToSwitch.switching = true; while (setToSwitch.set.TryTake(out nextTask)) { RunOrQueue(nextTask); } while (setToSwitch.busy > 0) { Thread.Sleep(new TimeSpan(TimeSpan.TicksPerMillisecond / 10)); } setToSwitch.scheduleOffset += NumberOfSets; setToSwitch.switching = false; nextSet++; } int delay; if (TasksToRunSoon.Count > 0) { delay = (int)(TasksToRunSoon[0].scheduledTime - DateTime.UtcNow).TotalMilliseconds; } else { delay = (int)((nextSet * MillisecondsPerSet) - (DateTime.UtcNow.Ticks - StartOffset) / TimeSpan.TicksPerMillisecond); } if (delay > 0) { //Wait until next timer. MaySleep.WaitOne(delay); //Don't really care why we woke up, either our own alarm or another thread. } } }