/// <summary> /// 调整定时器的触发时 /// </summary> /// <param name="timerID">定时器ID</param> /// <param name="newTimeOut">新的时间</param> public void ProlongTimer(long timerID, DateTime newTimeOut) { lock (this) { if (_addList.ContainsKey(timerID)) { ParamTimerData t = (ParamTimerData)_addList[timerID]; t.timeOut = newTimeOut; return; } if (_timerPool.Contains(timerID)) { ParamTimerData t = (ParamTimerData)_timerPool[timerID]; DateTime oldTimeOut = t.timeOut; t.timeOut = newTimeOut; if (oldTimeOut != t.timeOut) { ArrayList timerList = (ArrayList)_sortedTimerPool[oldTimeOut]; if (timerList != null) { for (int i = timerList.Count - 1; i >= 0; i--) { if (((ParamTimerData)timerList[i]).id == timerID) { timerList.RemoveAt(i); } } if (timerList.Count == 0) { _sortedTimerPool.Remove(oldTimeOut); } } timerList = (ArrayList)_sortedTimerPool[t.timeOut]; if (timerList == null) { timerList = new ArrayList(); _sortedTimerPool.Add(t.timeOut, timerList); } timerList.Insert(0, t);//倒着插入 } return; } } }
/// <summary> /// 获取定时器触发的剩余时间ms /// </summary> /// <param name="timerID">定时器ID</param> /// <returns>返回剩余时间,毫秒级</returns> public long GetTimerTime(long timerID) { lock (this) { if (_addList.ContainsKey(timerID)) { ParamTimerData t = (ParamTimerData)_addList[timerID]; return(GetInterval(t.timeOut, GetTime(0))); } if (_timerPool.Contains(timerID)) { ParamTimerData t = (ParamTimerData)_timerPool[timerID]; return(GetInterval(t.timeOut, GetTime(0))); } return(0); } }
/// <summary> /// 添加定时器 /// </summary> /// <param name="cb">回调函数</param> /// <param name="interval">间隔ms</param> /// <param name="times">调用次数,-1表示一直循环</param> /// <param name="param">回调参数</param> /// <returns>返回定时器ID</returns> public long AddTimer(ParamTimerCallback cb, long interval, int times, object param) { lock (this) { if (interval < _precision) { interval = _precision; } ParamTimerData data = new ParamTimerData(); data.id = ++TimerID; data.interval = interval; data.lastTime = GetTime(0); data.timeOut = GetTime(interval); data.times = 0; data.totalTimes = times; data.cb = cb; data.param = param; _addList.Add(data.id, data); return(data.id); } }
/// <summary> /// 定时器调度,有执行限制时长ms /// </summary> /// <param name="exceptions">输出异常队列</param> /// <param name="restrictInterval">执行限制时长,毫秒级</param> /// <param name="pmdel">内存统计接口</param> public void Schedule(ArrayList exceptions, long restrictInterval, PrintMemoryFluxDele pmdel) { lock (this) { DateTime time = GetTime(0); foreach (ParamTimerData t in _addList.Values) { _timerPool.Add(t.id, t); ArrayList timerList = (ArrayList)_sortedTimerPool[t.timeOut]; if (timerList == null) { timerList = new ArrayList(); _sortedTimerPool.Add(t.timeOut, timerList); } timerList.Insert(0, t);//倒着插入 } _addList.Clear(); foreach (long timerID in _delList) { ParamTimerData t = (ParamTimerData)_timerPool[timerID]; if (t != null) { _timerPool.Remove(timerID); ArrayList timerList = (ArrayList)_sortedTimerPool[t.timeOut]; if (timerList != null) { for (int i = timerList.Count - 1; i >= 0; i--) { if (((ParamTimerData)timerList[i]).id == timerID) { timerList.RemoveAt(i); } } if (timerList.Count == 0) { _sortedTimerPool.Remove(t.timeOut); } } } } _delList.Clear(); bool bTimerOut = false; ArrayList delTimerList = new ArrayList(); foreach (DateTime timeOut in _sortedTimerPool.Keys) { if (timeOut <= time) { ArrayList timerList = (ArrayList)_sortedTimerPool[timeOut]; if (timerList == null || timerList.Count <= 0) { delTimerList.Add(timeOut); } else { for (int i = timerList.Count - 1; i >= 0; i--) { ParamTimerData t = (ParamTimerData)timerList[i]; try { if (pmdel != null) { pmdel("SortedParamTimer.Before." + t.cb.Method.Name); } if (t == null || t.cb == null) { SvLogger.Info("Schedule Exception : ID={0}, LastTime={1}, TimeOut={2}.", t == null ? -1 : t.id, t == null ? "1900-01-01 00:00:00" : t.lastTime.ToString("yyyy-MM-dd HH:mm:ss"), t == null ? "1900-01-01 00:00:00" : t.timeOut.ToString("yyyy-MM-dd HH:mm:ss")); } t.cb(t.times++, GetInterval(time, t.lastTime), t.id, t.param); if (pmdel != null) { pmdel("SortedParamTimer.After." + t.cb.Method.Name); } } catch (Exception ex) { if (exceptions != null) { exceptions.Add(ex); } } t.lastTime = time; t.timeOut = time.AddMilliseconds(-(GetInterval(time, t.timeOut) % t.interval) + t.interval); timerList.RemoveAt(i); _timerPool.Remove(t.id); if (t.times < t.totalTimes || t.totalTimes == -1) { _addList.Add(t.id, t); } if (restrictInterval > 0 && time.AddMilliseconds(restrictInterval) <= GetTime(0)) { bTimerOut = true; break; } } if (timerList.Count == 0) { delTimerList.Add(timeOut); } } if (bTimerOut) { break; } } else { break; } } foreach (DateTime timeOut in delTimerList) { _sortedTimerPool.Remove(timeOut); } } }