PollModule.cs 8.55 KB
Newer Older
潘栩锋's avatar
潘栩锋 committed
1 2 3 4
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
5
using System.Windows.Threading;
潘栩锋's avatar
潘栩锋 committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222

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)
                {
                    pollmember.RemoveAll(p => p.pollfunc == pollfunc);
                }
                else
                {
                    pollmember.RemoveAll(p => p.owner == owner && p.markno == markno);
                }
            }
        }
        
        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.RemoveAt(i);
                            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;
223 224
        System.Windows.Threading.DispatcherTimer timer;
        public Dispatcher Dispatcher;
潘栩锋's avatar
潘栩锋 committed
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
        /// <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;
                }  
            };
241
            Dispatcher = timer.Dispatcher;
潘栩锋's avatar
潘栩锋 committed
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
        }
        bool mylock=false;
        /// <summary>
        /// 启动OnPoll
        /// </summary>
        public void Start() 
        {
            timer.Start();
        }
        /// <summary>
        /// 停止OnPoll
        /// </summary>
        public void Stop() 
        {
            timer.Stop();
        }
    }
    
}