Beispiel #1
0
        /// <summary>
        /// Timer的时间检测函数,这里是独立线程
        /// 但只负责检查时间片,不负责任务执行
        /// </summary>
        private static void RunTimerThread()
        {
            s_threadQueue = ThreadQueue.GetThreadQueue("TimeSlice");

            Logs.Info("Time slice: Time slice thread start!");

            bool             bSkipWait     = false; // 是否跳过等待
            const int        longTimeIndex = 3;
            List <TimeSlice> remove        = new List <TimeSlice>();

            while (GameServerService.RunType != ServerStateType.Closing)
            {
                if (bSkipWait)
                {
                    bSkipWait = false; // 恢复原始设置
                }
                else
                {
                    s_Signal.WaitOne(1); // 等待让其它的CPU有机会处理
                }
                // 先处理改变了优先级的时间片集合
                ProcessChangeQueue();

                // 这里只先处理前3种时间片数据
                long     iIndex;
                DateTime nowDateTime = OneServer.NowTime;
                for (iIndex = 0; iIndex < longTimeIndex; iIndex++)
                {
                    #region 执行普通的时间片的检查

                    // 如果小于下一次处理的时间片就跳出
                    if (nowDateTime < s_NextPriorities[iIndex])
                    {
                        break;
                    }

                    // 设置下一次处理的时间片
                    s_NextPriorities[iIndex] = nowDateTime + s_PriorityDelays[iIndex];

                    foreach (TimeSlice timeSlice in s_Timers[iIndex])
                    {
                        // 如果当前时间片已经处理过,已不在先入先出的集合中,并且当前的时间大于下一次调用的时间
                        if (nowDateTime >= timeSlice.NextTime)
                        {
                            // 将定时任务压入业务逻辑处理线程里
                            if (timeSlice.RunType == TimeSliceRunType.LogicTask)
                            {
                                MainTask.AppendTask(timeSlice.OnTick);
                            }
                            else
                            {
                                s_threadQueue.Append(timeSlice.OnTick);
                            }

                            // 调用次数累加 1
                            timeSlice.m_NumberOfTimes++;

                            // 如果运行次数大于等于当前的时间片的运行数量话就停止(如果只运行一次的话就马上调用停止,下次运行将从列表中移去,因为已经加入了TimeSlice.s_TimeSliceQueue集合所以会调用一次的)
                            bool needStop = false;
                            if (timeSlice.Times <= 0) // 检测可调用的次数
                            {
                                needStop = true;
                            }
                            else if (timeSlice.NumberOfTimes >= timeSlice.Times) // 检测调用的次数是否大于或等于最大的调用次数
                            {
                                needStop = true;
                            }
                            else if (nowDateTime >= timeSlice.StopTime) //  检测当前时间是否大于或等于最大的停止时间
                            {
                                needStop = true;
                            }
                            else
                            {
                                timeSlice.NextTime = nowDateTime + timeSlice.IntervalTime; // 计算下次调用的时间
                            }
                            if (needStop)
                            {
                                if (timeSlice.RunType == TimeSliceRunType.LogicTask)
                                {
                                    MainTask.AppendTask(timeSlice.Stop);
                                }
                                else
                                {
                                    s_threadQueue.Append(timeSlice.Stop);
                                }

                                RemoveTimer(timeSlice);
                            }
                            if (timeSlice.Frequency == TimerFrequency.LongTime)
                            {
                                remove.Add(timeSlice);
                            }
                        }
                    }

                    if (remove.Count > 0)
                    {
                        //  内部移除,就不必要走线程处理了
                        remove.ForEach(o => s_Timers[iIndex].Remove(o));
                    }
                    #endregion
                }

                //  长时间操作队列把对象放入1s间隔的检查队列里
                if (nowDateTime > s_NextPriorities[longTimeIndex])
                {
                    s_NextPriorities[longTimeIndex] = nowDateTime + s_PriorityDelays[longTimeIndex];
                    var checkTime = nowDateTime.AddMinutes(1);
                    foreach (TimeSlice timeSlice in s_Timers[longTimeIndex])
                    {
                        if (timeSlice.NextTime < checkTime)
                        {
                            s_Timers[longTimeIndex - 1].Add(timeSlice);
                        }
                    }
                }

                // 检查是否有马上需要执行的时间片
                nowDateTime = OneServer.NowTime;
                if (s_Timers[(int)TimerFrequency.EveryTick].Count > 0)
                {
                    bSkipWait = true;
                }
                else if (nowDateTime >= s_NextPriorities[1]) // 检查100毫秒的时间片
                {
                    bSkipWait = true;
                }
            }
        }