using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Threading; namespace FObjBase { /// <summary> /// 循环执行模块,可以认为就是定时器系统 /// </summary> public class PollModule { /// <summary> /// Poll_Config 的动作,添加,删除 /// </summary> public enum POLL_CONFIG { /// <summary> /// 添加 /// </summary> ADD, /// <summary> /// 删除 /// </summary> REMOVE } /// <summary> /// 循环执行的事件 /// </summary> public delegate void PollHandler(); /// <summary> /// 静态的实例,平常就是只用它 /// </summary> public static PollModule Current = new PollModule(); /// <summary> /// 精确执行,也就是一次OnPoll 一直While ,直到时间结束 /// </summary> public bool IsAccurate = false; class PollStruct { public PollHandler pollfunc; public TimeSpan ts; public DateTime dt = DateTime.MinValue; public bool bJustOnce; public object owner; public int markno; } List<PollStruct> pollmember = new List<PollStruct>(); /// <summary> /// 以100ms 为周期, 多次执行 /// </summary> /// <param name="pollfunc"></param> public void Poll_Config(PollHandler pollfunc) { Poll_Config(POLL_CONFIG.ADD, pollfunc); } /// <summary> /// 以100ms 为周期, 多次执行 /// </summary> /// <param name="action"></param> /// <param name="pollfunc"></param> public void Poll_Config(POLL_CONFIG action, PollHandler pollfunc) { Poll_Config(action, pollfunc, new TimeSpan(TimeSpan.TicksPerMillisecond * 100)); } /// <summary> /// 多次周期执行 /// </summary> /// <param name="action"></param> /// <param name="pollfunc"></param> /// <param name="ts"></param> public void Poll_Config(POLL_CONFIG action, PollHandler pollfunc, TimeSpan ts) { Poll_Config(action, pollfunc, ts, true, false, null, 0, false); } /// <summary> /// 添加或删除 poll func, 当pollfunc 本来已经存在,再次添加,只会使计时重新,或不管!! /// </summary> /// <param name="action">动作,添加?删除?</param> /// <param name="pollfunc">周期执行函数</param> /// <param name="ts">时间间隔</param> /// <param name="bRestart">重新计算数据</param> /// <param name="bActByNow">立刻执行?</param> /// <param name="owner">该函数的拥有者</param> /// <param name="markno">对func的标识码</param> /// <param name="bJustOnce">只执行一次</param> public void Poll_Config(POLL_CONFIG action, PollHandler pollfunc, TimeSpan ts, bool bRestart, bool bActByNow, object owner, int markno, bool bJustOnce) { if (action == POLL_CONFIG.ADD) { //周期执行的,执行周期最小为1ms if ((ts.TotalMilliseconds) < 1 && (bJustOnce == false)) ts = new TimeSpan(TimeSpan.TicksPerMillisecond); PollStruct ps; if (owner == null) { ps = pollmember.Find(p => p.pollfunc == pollfunc); } else { ps = pollmember.Find(p => p.owner == owner && p.markno == markno); } if (ps == null)//新的!!!! { ps = new PollStruct() { pollfunc = pollfunc, ts = ts, owner = owner, markno = markno }; pollmember.Add(ps); } else { if (ps.ts != ts) { ps.ts = ts; } if (bRestart) { ps.dt = DateTime.MinValue; } } ps.bJustOnce = bJustOnce; if (bActByNow) //立刻执行 { ps.dt = DateTime.MaxValue; } } else { if (owner == null) { Poll_Remove(pollfunc); } else { Poll_Remove(owner,markno); } } } public void Poll_Remove(PollHandler pollfunc) { pollmember.RemoveAll(p => p.pollfunc == pollfunc); } public void Poll_Remove(object owner, int markno) { pollmember.RemoveAll(p => p.owner == owner && p.markno == markno); } /// <summary> /// 多次周期执行 /// </summary> /// <param name="pollfunc"></param> /// <param name="ts"></param> public void Poll_Config(PollHandler pollfunc, TimeSpan ts) { Poll_Config(pollfunc, ts, true, false, null, 0, false); } /// <summary> /// 添加或删除 poll func, 当pollfunc 本来已经存在,再次添加,只会使计时重新,或不管!! /// </summary> /// <param name="pollfunc">周期执行函数</param> /// <param name="ts">时间间隔</param> /// <param name="bRestart">重新计算数据</param> /// <param name="bActByNow">立刻执行?</param> /// <param name="owner">该函数的拥有者</param> /// <param name="markno">对func的标识码</param> /// <param name="bJustOnce">只执行一次</param> public void Poll_Config(PollHandler pollfunc, TimeSpan ts, bool bRestart, bool bActByNow, object owner, int markno, bool bJustOnce) { Poll_Config(POLL_CONFIG.ADD, pollfunc, ts, bRestart, bActByNow, owner, markno, bJustOnce); } public void OnPoll() { DateTime dt = DateTime.Now; PollStruct ps; for (int i = 0; i < pollmember.Count(); i++) { ps = pollmember[i]; while (true) { bool toact = false; if (ps.dt == DateTime.MaxValue)//立刻执行 { ps.dt = dt; toact = true; } else if (ps.dt == DateTime.MinValue) //刚加入 { ps.dt = dt; } else { TimeSpan ts = dt - ps.dt; if (ts<TimeSpan.Zero)//异常,有人改了系统时间,时间回到从前了 { ps.dt = dt; } else if (ts >= ps.ts)//够钟了!! { if (IsAccurate)//精密!!!! { ps.dt = ps.dt + ps.ts; //当超过得太多,没法精确了,超过了10次 //if (ps.ts.TotalMilliseconds * 20 < ts.TotalMilliseconds) //{ // ps.dt = dt; //} } else { ps.dt = dt; } toact = true; } } if (toact) { ps.pollfunc(); if (ps.bJustOnce) { //从列表中删除 pollmember.Remove(ps); i--; } else if (IsAccurate) { continue; } } break; } } } /// <summary> /// 只为了延时操作,同一周期多次添加同一func,只会调到一次!!! /// </summary> /// <param name="pollfunc"></param> /// <param name="owner"></param> /// <param name="markno"></param> public void Poll_JustOnce(PollHandler pollfunc, object owner, int markno) { Poll_Config(POLL_CONFIG.ADD, pollfunc, new TimeSpan(), false, true, owner, markno, true); } static DateTime dt_last = DateTime.Now; System.Windows.Threading.DispatcherTimer timer; public Dispatcher Dispatcher; /// <summary> /// 不需要自己创建实例,因为已经创建了静态的对象 /// </summary> public PollModule() { timer = new System.Windows.Threading.DispatcherTimer(); timer.Interval = TimeSpan.FromMilliseconds(1); timer.Tick += (s, e) => { if (mylock != true)//不能让它能重入 { mylock = true; OnPoll(); mylock = false; } }; Dispatcher = timer.Dispatcher; } bool mylock=false; /// <summary> /// 启动OnPoll /// </summary> public void Start() { timer.Start(); } /// <summary> /// 停止OnPoll /// </summary> public void Stop() { timer.Stop(); } } }