/// <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; } } }