计时器类,应用在一个拍卖程序

  1    /// <summary>
  2     /// 提供计时器服务
  3     /// </summary>
  4     public class TimerService
  5     {
  6         private static TimerService _Instance = null;
  7 
  8         public static TimerService Instance
  9         {
 10             get
 11             {
 12                 if (_Instance == null)
 13                 {
 14                     //实例化对象,并启动计时器服务
 15                     _Instance = new TimerService();
 16                     _Instance.timer = new System.Timers.Timer();
 17                     _Instance.timer.Interval = 1000;
 18                     _Instance.timer.Elapsed += _Instance.Timer_Elapsed;
 19                     _Instance.timer.Start();
 20                 }
 21                 return _Instance;
 22             }
 23         }
 24 
 25         /// <summary>
 26         /// 定时器读写锁
 27         /// </summary>
 28         private UsingLock<Object> Lock = new UsingLock<object>();
 29 
 30         /// <summary>
 31         /// 已注册的事件列表
 32         /// </summary>
 33         private List<TimerEventInfomation> SubscribedEvents = new List<TimerEventInfomation>();
 34 
 35         /// <summary>
 36         /// 计时器,每秒计时一次
 37         /// </summary>
 38         private System.Timers.Timer timer = new System.Timers.Timer();
 39 
 40         /// <summary>
 41         /// 获取当前时间戳
 42         /// </summary>
 43         /// <returns></returns>
 44         private long GetTime()
 45         {
 46             return GetTime(DateTime.Now);
 47         }
 48 
 49         /// <summary>
 50         /// 获取指定日期时间的时间戳
 51         /// </summary>
 52         /// <param name="time"></param>
 53         /// <returns></returns>
 54         public static long GetTime(DateTime time)
 55         {
 56             return Convert.ToInt32(time.Subtract(DateTime.Parse("1970-01-01")).TotalSeconds);
 57         }
 58 
 59         /// <summary>
 60         /// 每秒触发一次该事件
 61         /// </summary>
 62         /// <param name="sender"></param>
 63         /// <param name="e"></param>
 64         private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
 65         {
 66             var time = GetTime();
 67             using (Lock.Write())
 68             {
 69                 var triggers = this.SubscribedEvents.Where(t => t.EventTime == time).ToList();
 70                 foreach (var item in triggers)
 71                 {
 72                     //异步执行回调
 73                     item.EventCallback?.BeginInvoke(item, new AsyncCallback((d) => { }), null);
 74                 }
 75                 //移除全部本次已回调的对象列表
 76                 foreach (var item in triggers)
 77                 {
 78                     this.SubscribedEvents.Remove(item);
 79                 }
 80             }
 81         }
 82 
 83         /// <summary>
 84         /// 添加一个事件到计时器
 85         /// </summary>
 86         /// <param name="info"></param>
 87         public void Add(TimerEventInfomation info)
 88         {
 89             using (Lock.Write())
 90             {
 91                 if (info.EventTime <= GetTime())
 92                 {
 93                     return;
 94                 }
 95                 Logs.Info($"为活动{info.ActiveID}新增计时器 -> " + Newtonsoft.Json.JsonConvert.SerializeObject(info));
 96                 this.SubscribedEvents.Add(info);
 97             }
 98         }
 99 
100         /// <summary>
101         /// 无则新增,有则更新,新增返回true,更新返回false
102         /// </summary>
103         /// <param name="info"></param>
104         public bool Set(TimerEventInfomation info)
105         {
106             using (Lock.Write())
107             {
108                 var obj = this.SubscribedEvents.Where(t => t.ActiveID == info.ActiveID && t.Category == info.Category).FirstOrDefault();
109                 if (obj == null)
110                 {
111                     obj.EventTime = info.EventTime;
112                     obj.callbackObject = info.callbackObject;
113                     obj.EventCallback = info.EventCallback;
114                     Logs.Info($"为活动{info.ActiveID}更新计时器 -> " + Newtonsoft.Json.JsonConvert.SerializeObject(info));
115                     return false;
116                 }
117                 else
118                 {
119                     this.SubscribedEvents.Add(info);
120                     Logs.Info($"为活动{info.ActiveID}新增计时器 -> " + Newtonsoft.Json.JsonConvert.SerializeObject(info));
121                     return true;
122                 }
123             }
124         }
125 
126         /// <summary>
127         /// 清空指定活动的计时器
128         /// </summary>
129         public int Remove(int ActiveID)
130         {
131             using (Lock.Write())
132             {
133                 var Removes = this.SubscribedEvents.FindAll(t => t.ActiveID == ActiveID).ToList();
134                 if (Removes != null && Removes.Count > 0)
135                 {
136                     Logs.Info($"移除活动{ActiveID}全部计时器 -> " + Newtonsoft.Json.JsonConvert.SerializeObject(Removes));
137                 }
138                 return this.SubscribedEvents.RemoveAll(t => t.ActiveID == ActiveID);
139             }
140         }
141 
142         /// <summary>
143         /// 移除掉指定类别的计时器,通常应用在举牌倒计时器,或者报名倒计时器,报名人满即将开始时自动清除报名倒计时器,或者活动成功结束后需要清理掉倒计时器
144         /// </summary>
145         /// <param name="ActiveID"></param>
146         /// <param name="category"></param>
147         public int Remove(int ActiveID, TimerEventInfomationCategorys category)
148         {
149             using (Lock.Write())
150             {
151                 return this.SubscribedEvents.RemoveAll(t => t.ActiveID == ActiveID && t.Category == category);
152             }
153         }
154 
155         /// <summary>
156         /// 重载版本
157         /// </summary>
158         /// <param name="ActiveID"></param>
159         /// <param name="eventTime"></param>
160         /// <param name="sender"></param>
161         /// <param name="callback"></param>
162         public void Add(int ActiveID, DateTime eventTime, object sender, Action<Object> callback)
163         {
164             if (eventTime <= DateTime.Now) { return; }
165             using (Lock.Write())
166             {
167                 var info = new TimerEventInfomation() { ActiveID = ActiveID, EventTime = GetTime(eventTime), callbackObject = sender, EventCallback = callback };
168                 Logs.Info($"为活动{info.ActiveID}新增计时器 -> " + Newtonsoft.Json.JsonConvert.SerializeObject(info));
169                 this.SubscribedEvents.Add(info);
170             }
171         }
172 
173         /// <summary>
174         /// 用于重置符合指定条件的计时器计时时间
175         /// </summary>
176         /// <param name="ActiveID"></param>
177         /// <param name="category"></param>
178         /// <param name="time"></param>
179         public void ResetTime(int ActiveID, TimerEventInfomationCategorys category, DateTime time)
180         {
181             if (time <= DateTime.Now) { return; }
182             using (Lock.Write())
183             {
184                 var ms = this.SubscribedEvents.Where(t => t.ActiveID == ActiveID && t.Category == category).ToList();
185                 ms.ForEach(new Action<TimerEventInfomation>((t) =>
186                 {
187                     t.EventTime = GetTime(time);
188                 }));
189                 Logs.Info($"为活动{ActiveID}更新类别{category.ToString()}计时器时间 -> " + Newtonsoft.Json.JsonConvert.SerializeObject(ms));
190             }
191         }
192 
193         /// <summary>
194         /// 计时器事件消息对象
195         /// </summary>
196         public class TimerEventInfomation
197         {
198             /// <summary>
199             /// 关联此事件的活动ID,用于批量重置或清除指定活动的全部事件
200             /// </summary>
201             public int ActiveID { get; set; }
202 
203             /// <summary>
204             /// 标识,用于对计时器事件归类,方便通过该标识结合
205             /// </summary>
206             public TimerEventInfomationCategorys Category { get; set; } = TimerEventInfomationCategorys.通用;
207 
208             /// <summary>
209             /// 事件时间,指定事件触发的具体时间
210             /// </summary>
211             public long EventTime { get; set; }
212 
213             /// <summary>
214             /// 回调时的参数对象
215             /// </summary>
216             public Object callbackObject = null;
217 
218             /// <summary>
219             /// 定时器自动触发的回调事件,当事件引发时,自动触发该回调
220             /// </summary>
221             public Action<Object> EventCallback { get; set; }
222         }
223 
224         /// <summary>
225         /// 归类枚举
226         /// </summary>
227         public enum TimerEventInfomationCategorys
228         {
229             通用 = 0,
230             /// <summary>
231             /// 表明活动已经开始,举牌进行中,等待目标时间表明倒计时时间已到
232             /// </summary>
233             落拍倒计时 = 2,
234             /// <summary>
235             /// 应用于定时开拍类活动,表示定时开拍,非定拍类活动不会使用到此枚举
236             /// </summary>
237             定拍倒计时 = 3,
238             /// <summary>
239             /// 开拍倒计时,指活动正式开始前的30秒倒计时期间,定时该计时器用于处理活动正式开始
240             /// </summary>
241             开拍倒计时 = 4,
242             /// <summary>
243             /// 托管自动举牌,人工出价类,每次有人出价时,自动重置,用于从托管用户中获取一个用户自动执行举牌,时间为倒计时剩余3秒时。举牌的同时自动重置。
244             /// </summary>
245             托管自动举牌 = 5,
246             /// <summary>
247             /// 提供给新活动自动轮询的计时器对象
248             /// </summary>
249             新活动轮询 = 6
250         }
251     }

 

posted @ 2019-10-03 11:16  soleds  阅读(242)  评论(0编辑  收藏  举报