using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Threading; namespace FObjBase { /// /// 循环执行模块,可以认为就是定时器系统 /// public class PollModule { /// /// Poll_Config 的动作,添加,删除 /// public enum POLL_CONFIG { /// /// 添加 /// ADD, /// /// 删除 /// REMOVE } /// /// 循环执行的事件 /// public delegate void PollHandler(); /// /// 静态的实例,平常就是只用它 /// public static PollModule Current = new PollModule(); /// /// 精确执行,也就是一次OnPoll 一直While ,直到时间结束 /// 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 pollmember = new List(); /// /// 以100ms 为周期, 多次执行 /// /// public void Poll_Config(PollHandler pollfunc) { Poll_Config(POLL_CONFIG.ADD, pollfunc); } /// /// 以100ms 为周期, 多次执行 /// /// /// public void Poll_Config(POLL_CONFIG action, PollHandler pollfunc) { Poll_Config(action, pollfunc, new TimeSpan(TimeSpan.TicksPerMillisecond * 100)); } /// /// 多次周期执行 /// /// /// /// public void Poll_Config(POLL_CONFIG action, PollHandler pollfunc, TimeSpan ts) { Poll_Config(action, pollfunc, ts, true, false, null, 0, false); } /// /// 添加或删除 poll func, 当pollfunc 本来已经存在,再次添加,只会使计时重新,或不管!! /// /// 动作,添加?删除? /// 周期执行函数 /// 时间间隔 /// 重新计算数据 /// 立刻执行? /// 该函数的拥有者 /// 对func的标识码 /// 只执行一次 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); } /// /// 多次周期执行 /// /// /// public void Poll_Config(PollHandler pollfunc, TimeSpan ts) { Poll_Config(pollfunc, ts, true, false, null, 0, false); } /// /// 添加或删除 poll func, 当pollfunc 本来已经存在,再次添加,只会使计时重新,或不管!! /// /// 周期执行函数 /// 时间间隔 /// 重新计算数据 /// 立刻执行? /// 该函数的拥有者 /// 对func的标识码 /// 只执行一次 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= 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; } } } /// /// 只为了延时操作,同一周期多次添加同一func,只会调到一次!!! /// /// /// /// 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; /// /// 不需要自己创建实例,因为已经创建了静态的对象 /// 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; /// /// 启动OnPoll /// public void Start() { timer.Start(); } /// /// 停止OnPoll /// public void Stop() { timer.Stop(); } } }