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();
}
}
}