public void TestExecutionOnTime()
        {
            var tickDuration       = TimeSpan.FromMilliseconds(200);
            var timeout            = TimeSpan.FromMilliseconds(125);
            var nanoTimeout        = NanoTime.FromMilliseconds(125);
            var maxTimeout         = 2 * (tickDuration + timeout);
            var nanoMaxTimeout     = NanoTime.FromMilliseconds(maxTimeout.TotalMilliseconds);
            HashedWheelTimer timer = new HashedWheelTimer(tickDuration);
            var queue = new BlockingCollection <long>();

            var watch = new ConcurrentStopwatch();

            watch.Start();
            int scheduledTasks = 100000;

            for (int i = 0; i < scheduledTasks; i++)
            {
                var start = watch.Elapsed;
                timer.ScheduleTimeout(() =>
                {
                    queue.Add(watch.Elapsed - start);
                }, timeout);
            }

            for (int i = 0; i < scheduledTasks; i++)
            {
                long delay = queue.Take();
                Assert.True(delay >= nanoTimeout && delay < nanoMaxTimeout, i + ": Timeout + " + scheduledTasks + " delay " + delay + " must be " + timeout + " < " + maxTimeout);
            }

            timer.Stop();
        }
 private void DefaultInitialize()
 {
     DefaultTimeout = NanoTime.FromSeconds(10);
     TicksInterval  = NanoTime.FromMilliseconds(50);
     InitializeSlots();
     workerThread = new Thread(WorkLoop);
     time.Start();
     workerThread.Start();
     ticked = 0;
 }
 /// <summary>
 /// Create a timer with custamizable ticks interval and default timeout of TimedCallback.
 /// </summary>
 /// <param name="interval"></param>
 /// <param name="defaultTimeout"></param>
 /// <param name="policy"></param>
 public HashedWheelTimer(TimeSpan interval, TimeSpan defaultTimeout, SleepPolicy policy = SleepPolicy.Default)
 {
     TicksInterval  = NanoTime.FromMilliseconds(interval.TotalMilliseconds);
     DefaultTimeout = NanoTime.FromMilliseconds(defaultTimeout.TotalMilliseconds);
     ticked         = 0;
     SetSleep(policy);
     InitializeSlots();
     workerThread = new Thread(WorkLoop);
     time.Start();
     workerThread.Start();
 }
        /// <summary>
        /// Schedule a new callback with specified timeout in milliseconds.
        /// </summary>
        /// <param name="action">Callback function to be fired when timeout.</param>
        /// <returns>A callback wrapper which allow user to cancel timeout.</returns>
        public TimedCallback ScheduleTimeout(Action action, double milliseconds)
        {
            if (milliseconds < 0)
            {
                throw new ArgumentException("Expiry time cannot be negative.", "timeout");
            }
            CheckTimerState();

            var nanoTimeout   = NanoTime.FromMilliseconds(milliseconds);
            var actualTimeout = time.Elapsed + nanoTimeout;
            var callback      = new TimedCallback(action, actualTimeout, this);

            Interlocked.Increment(ref timeoutsCount);
            Interlocked.Increment(ref activeTimeoutsCount);
            ScheduleTimeoutImpl(callback, actualTimeout);

            return(callback);
        }
 /// <summary>
 /// Create a timer with specified tick interval and sleep policy.
 /// </summary>
 /// <param name="interval">ticks interval</param>
 /// <param name="policy">Sleep policy</param>
 public HashedWheelTimer(TimeSpan interval, SleepPolicy policy = SleepPolicy.Default)
     : this(policy)
 {
     TicksInterval = NanoTime.FromMilliseconds(interval.TotalMilliseconds);
 }