EventManage.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. using ProjectBase.Data.Logs;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace SIASUN.Autopilot.Device
  9. {
  10. #region 事件链
  11. public class EventManage
  12. {
  13. static EventManage _instance;
  14. public static EventManage Instance
  15. {
  16. get
  17. {
  18. if (_instance == null)
  19. {
  20. _instance = new EventManage();
  21. _instance.EventBuffer = new Dictionary<string, List<object>>();
  22. }
  23. return _instance;
  24. }
  25. }
  26. /// <summary>
  27. /// 对于分包数据,在此根据事件名称缓存包的消息体数据
  28. /// </summary>
  29. public Dictionary<string, List<object>> EventBuffer { get; private set; }
  30. /// <summary>
  31. /// 跟踪所有事件的注册和订阅
  32. /// </summary>
  33. private Hashtable delegateMap = new Hashtable();
  34. /// <summary>
  35. /// 订阅事件添加到客户端的委托。
  36. /// </summary>
  37. /// <param name="eventName">事件名称。</param>
  38. /// <param name="handler">客户端的委托句柄。</param>
  39. public void SubscribeEvent(string eventName, EventProcessingHandler handler)
  40. {
  41. // 确保同一时间只有一个线程来修改委托链。
  42. lock (this)
  43. {
  44. // 检查委托链是否为null。
  45. // 如果为null,则添加客户端委托作为初始句柄,
  46. // 否则,添加委托到链表中。
  47. if (!delegateMap.ContainsKey(eventName))
  48. {
  49. delegateMap.Add(eventName, handler);
  50. }
  51. else
  52. {
  53. Delegate delegateChain = (Delegate)delegateMap[eventName];
  54. // 添加委托到链表中
  55. delegateChain = Delegate.Combine(delegateChain, handler);
  56. // 在Hashtable中重置委托链
  57. delegateMap[eventName] = delegateChain;
  58. }
  59. }
  60. }
  61. /// <summary>
  62. /// 取消事件订阅,从委托链中移除客户端的委托
  63. /// </summary>
  64. /// <param name="eventName">事件名称</param>
  65. /// <param name="handler"></param>
  66. public void UnSubscribeEvent(string eventName, EventProcessingHandler handler)
  67. {
  68. // 确保同一时间只有一个线程来修改委托链。
  69. lock (this)
  70. {
  71. Delegate delegateChain = (Delegate)delegateMap[eventName];
  72. // 检查委托链是否为null。
  73. // 如果不为null,则从委托链中移除。
  74. if (delegateChain != null)
  75. {
  76. // 移除
  77. delegateChain = Delegate.Remove(delegateChain, handler);
  78. if (delegateChain == null)
  79. {
  80. delegateMap.Remove(eventName);
  81. }
  82. else
  83. {
  84. // 在Hashtable中重置委托链
  85. delegateMap[eventName] = delegateChain;
  86. }
  87. }
  88. }
  89. }
  90. /// <summary>
  91. /// 提出事件调用指定事件的委托链。
  92. /// </summary>
  93. /// <param name="eventName">事件名称。</param>
  94. /// <param name="content">通知的内容。</param>
  95. public void RaiseEvent(string eventName, IList<object> content)
  96. {
  97. Delegate delegateChain = (Delegate)delegateMap[eventName];
  98. if (delegateChain == null)
  99. {
  100. string msg = string.Format("没有找到消息{0}的订阅事件", eventName);
  101. LogHelper.log.Error(msg);
  102. return;
  103. }
  104. delegateChain.DynamicInvoke(new PackageProcessingEventArgs(content));
  105. return;
  106. // 找回链表中的委托。
  107. IEnumerator invocationEnumerator = delegateChain.GetInvocationList().GetEnumerator();
  108. // 遍历查找并调用。
  109. while (invocationEnumerator.MoveNext())
  110. {
  111. Delegate handler = (Delegate)invocationEnumerator.Current;
  112. try
  113. {
  114. handler.DynamicInvoke(new object[] { eventName, content });
  115. }
  116. catch (Exception ex)
  117. {
  118. string msg = string.Format("遍历查找事件{0}时出现错误:{1}。", eventName, ex.Message);
  119. LogHelper.log.Error(msg);
  120. // 如果接收事件通知的客户端不存在,则移除此委托。
  121. //delegateChain = Delegate.Remove(delegateChain, handler);
  122. //delegateMap[eventName] = delegateChain;
  123. }
  124. }
  125. }
  126. }
  127. #endregion 事件链
  128. #region eventargs
  129. /// <summary>
  130. /// 接收到数据后,将包数据传递给调用者
  131. /// </summary>
  132. /// <param name="packageBytes"></param>
  133. public delegate void EventProcessingHandler(PackageProcessingEventArgs e);
  134. public class PackageProcessingEventArgs : EventArgs
  135. {
  136. public IList<object> PackageBytes { get; set; }
  137. public PackageProcessingEventArgs(IList<object> packageBytes)
  138. {
  139. this.PackageBytes = packageBytes;
  140. }
  141. }
  142. /// <summary>
  143. /// 接收到数据拆包后,将消息通知给调用者
  144. /// </summary>
  145. /// <param name="message"></param>
  146. public delegate void ReceiveMessageEventHandler(ReceiveMessageEventArgs e);
  147. public class ReceiveMessageEventArgs : EventArgs
  148. {
  149. public object Message { get; set; }
  150. public ReceiveMessageEventArgs(object message)
  151. {
  152. this.Message = message;
  153. }
  154. }
  155. #endregion
  156. }