Example #1
0
        /// <summary>
        /// 刷新时间
        /// </summary>
        /// <param name="state"></param>
        private static void refreshTime(object state)
        {
            System.Threading.Interlocked.Increment(ref refreshTimeThreadCount);
            DateTime now = DateTime.Now;

            Now    = now;
            UtcNow = now.localToUniversalTime();
            timer.Change(TimerInterval = 1000L - now.Millisecond, -1);

            do
            {
                long nextSecondTicks = NextSecondTicks;
                if (nextSecondTicks <= Now.Ticks)
                {
                    if (System.Threading.Interlocked.CompareExchange(ref NextSecondTicks, nextSecondTicks + TimeSpan.TicksPerSecond, nextSecondTicks) == nextSecondTicks)
                    {
                        System.Threading.Interlocked.Increment(ref CurrentSeconds);
                        try
                        {
                            SecondTimerNode node = SecondNodeLink.End;
                            if (node != null)
                            {
                                SecondTimerNode.LinkOnTimer(node);
                            }

                            if (System.Threading.Interlocked.CompareExchange(ref InternalTaskArray.TimerLinkLock.SleepFlag, 1, 0) == 0)
                            {
                                try
                                {
                                    ThreadPool.CheckExit();

                                    InternalTaskArray.OnTimer();
                                }
                                finally { System.Threading.Interlocked.Exchange(ref InternalTaskArray.TimerLinkLock.SleepFlag, 0); }
                            }

                            if (System.Threading.Interlocked.CompareExchange(ref TaskArray.TimerLinkLock.SleepFlag, 1, 0) == 0)
                            {
                                try
                                {
                                    TaskArray.OnTimer();
                                }
                                finally { System.Threading.Interlocked.Exchange(ref TaskArray.TimerLinkLock.SleepFlag, 0); }
                            }
                        }
                        catch (Exception exception)
                        {
                            AutoCSer.LogHelper.Exception(exception, "全局定时任务错误中断", LogLevel.AutoCSer | LogLevel.Exception | LogLevel.Fatal);
                        }
                    }
                }
                else
                {
                    System.Threading.Interlocked.Decrement(ref refreshTimeThreadCount);
                    return;
                }
            }while (true);
        }
        /// <summary>
        /// 尝试执行定时任务
        /// </summary>
        internal void OnTimer()
        {
            SecondTimerNode node = NodeLink.End;

            if (node != null)
            {
                SecondTimerNode.LinkOnTimer(node);
            }

            SecondTimerTaskNode head;

            do
            {
                TimerLinkLock.Enter();
                long seconds = linkArrayBaseSeconds + linkArrayIndex;
                if (seconds < SecondTimer.CurrentSeconds)
                {
                    head = linkArray[linkArrayIndex++].GetClear();
                    if (linkArrayIndex == linkArrayCapacity)
                    {
                        linkArrayIndex        = 0;
                        linkArrayBaseSeconds += linkArrayCapacity;

                        SecondTimerTaskNode nextHead = nextLinkArray[nextLinkArrayIndex++].GetClear();
                        while (nextHead != null)
                        {
                            nextHead = linkArray[(int)(nextHead.TimeoutSeconds - linkArrayBaseSeconds)].AppendOtherHead(nextHead);
                        }

                        if (nextLinkArrayIndex == linkArrayCapacity)
                        {
                            nextLinkArrayIndex = 0;

                            long baseSeconds = linkArrayBaseSeconds + linkArrayCapacity, maxSeconds = baseSeconds + (linkArrayCapacity << linkArrayBitSize);
                            nextHead = timerLink.GetClear();
                            while (nextHead != null)
                            {
                                if (nextHead.TimeoutSeconds < maxSeconds)
                                {
                                    nextHead = nextLinkArray[(int)(nextHead.TimeoutSeconds - baseSeconds) >> linkArrayBitSize].AppendOtherHead(nextHead);
                                }
                                else
                                {
                                    nextHead = timerLink.AppendOtherHead(nextHead);
                                }
                            }
                        }
                    }
                    TimerLinkLock.Exit();

                    while (head != null)
                    {
                        try
                        {
                            do
                            {
                                head.Call(ref head);
                            }while (head != null);
                        }
                        catch (Exception exception)
                        {
                            AutoCSer.LogHelper.Exception(exception, null, LogLevel.AutoCSer | LogLevel.Exception);
                        }
                    }
                }
                else
                {
                    TimerLinkLock.Exit();
                    return;
                }
            }while (true);
        }