Beispiel #1
0
        /// <summary>
        /// 外部调用,每隔一定的时间Tick一次
        /// </summary>
        public virtual void Tick()
        {
            if (mIsPaused)
            {
                return;
            }

            uint now     = GetCurrentMillisecond();
            uint loopNum = now > mCheckTime ? (now - mCheckTime) / Granularity : 0;

            TimeWheel wheel = mTimeWheels[0];

            for (uint i = 0; i < loopNum; ++i)
            {
                LinkedList <TimerNode> spoke;
                if (wheel.TryGetSpoke((int)wheel.CurrentSpokeIndex, out spoke))
                {
                    for (var timerNodeHost = spoke.First; timerNodeHost != null;)
                    {
                        var nextTimerNodeHost = timerNodeHost.Next;
                        timerNodeHost.List.Remove(timerNodeHost);
                        timerNodeHost.Value.TimerNodeHost = null;
                        --mTotalTimerNum;
                        AddToReadyList(timerNodeHost);
                        timerNodeHost = nextTimerNodeHost;
                    }
                }

                mCheckTime += Granularity;

                ++wheel.CurrentSpokeIndex;
                if (wheel.CurrentSpokeIndex >= wheel.MaxSpokes)
                {
                    wheel.CurrentSpokeIndex = 0;
                    Cascade(1);
                }
            }

            DoTimeoutCallback();

            if (mAutoPauseMode && mTotalTimerNum <= 0)
            {
                Pause();
            }
        }
Beispiel #2
0
        protected TimerManager(uint granularity = 20)
        {
            if (granularity <= 0)
            {
                throw new Exception("Granularity must be > 0");
            }
            Granularity = granularity;

            mAutoPauseMode = true;
            mTimeWheels    = new TimeWheel[5];
            mTimeWheels[0] = new TimeWheel(256);
            for (int i = 1; i < 5; ++i)
            {
                mTimeWheels[i] = new TimeWheel(64);
            }
            mReadyToInvokeList = new LinkedList <TimerNode>();
            mTimerNodeCache    = new Stack <TimerNode>();
        }
Beispiel #3
0
        /// <summary>
        /// 上一个时间轮转过一轮后,检索下一个时间轮当前插槽中的定时器
        /// </summary>
        /// <param name="wheelIndex"></param>
        protected virtual void Cascade(uint wheelIndex)
        {
            if (wheelIndex < 1 || wheelIndex >= 5)
            {
                return;
            }

            TimeWheel wheel             = mTimeWheels[wheelIndex];
            int       currentSpokeIndex = (int)wheel.CurrentSpokeIndex;

            ++wheel.CurrentSpokeIndex;
            LinkedList <TimerNode> spoke;

            if (wheel.TryGetSpoke(currentSpokeIndex, out spoke))
            {
                for (var timerNodeHost = spoke.First; timerNodeHost != null;)
                {
                    var nextTimerNodeHost = timerNodeHost.Next;
                    timerNodeHost.List.Remove(timerNodeHost);
                    var timerNode = timerNodeHost.Value;
                    --mTotalTimerNum;
                    if (timerNode.DeadTime <= mCheckTime)
                    {
                        timerNode.TimerNodeHost = null;
                        AddToReadyList(timerNodeHost);
                    }
                    else
                    {
                        AddTimerNode(timerNode.DeadTime - mCheckTime, timerNode);
                    }
                    timerNodeHost = nextTimerNodeHost;
                }
            }

            if (wheel.CurrentSpokeIndex >= wheel.MaxSpokes)
            {
                wheel.CurrentSpokeIndex = 0;
                Cascade(++wheelIndex);
            }
        }