System.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. using System.Collections.Concurrent;
  2. using System.Diagnostics;
  3. using System.Reflection;
  4. namespace WCS.Core
  5. {
  6. public abstract class SystemBase : DescriptionClass
  7. {
  8. public World World { get; private set; }
  9. public SystemBase()
  10. {
  11. var attr = this.GetType().GetCustomAttribute<BelongToAttribute>();
  12. if (attr == null) return;
  13. var wt = attr.WorldType;
  14. World = World.Worlds.First(v => v.GetType() == wt);
  15. }
  16. public abstract List<object> GetObjects();
  17. public abstract void Update(List<WorkTimes> list);
  18. }
  19. public abstract class SystemBase<T> : SystemBase
  20. {
  21. public List<T> Objects { get; set; }
  22. /// <summary>
  23. /// 对所有Objects并行循环执行Do
  24. /// </summary>
  25. protected abstract bool ParallelDo { get; }
  26. /// <summary>
  27. /// 保存日志到文件
  28. /// </summary>
  29. protected abstract bool SaveLogsToFile { get; }
  30. public SystemBase()
  31. {
  32. Objects = Create();//.Select(v=>Activator.CreateInstance(typeof(T),v)).OfType<T>().ToList();
  33. }
  34. public override void Update(List<WorkTimes> list)
  35. {
  36. if (ParallelDo)
  37. {
  38. Parallel.ForEach(Objects, new ParallelOptions { MaxDegreeOfParallelism = 256 }, obj =>
  39. {
  40. var sw = new Stopwatch();
  41. sw.Start();
  42. InvokeDo(obj);
  43. sw.Stop();
  44. list.AddSafe(new WorkTimes { Key = $"{obj?.ToString()}", Total = sw.ElapsedMilliseconds });
  45. });
  46. }
  47. else
  48. {
  49. foreach (var obj in Objects)
  50. {
  51. var sw = new Stopwatch();
  52. sw.Start();
  53. InvokeDo(obj);
  54. sw.Stop();
  55. list.AddSafe(new WorkTimes { Key = $"{obj?.ToString()}", Total = sw.ElapsedMilliseconds });
  56. }
  57. }
  58. }
  59. private void InvokeDo(T obj)
  60. {
  61. var channel = new Channel
  62. {
  63. World = World.Description,
  64. Stage = "DoLogics",
  65. System = Description,
  66. Item = obj.ToString()
  67. };
  68. try
  69. {
  70. if (channel.Item == "1")
  71. {
  72. var a = 1;
  73. }
  74. Ltc.SetChannel(channel);
  75. World.OnInternalLog(channel, "开始");
  76. Do(obj);
  77. }
  78. catch (Exception ex)
  79. {
  80. World.OnError(channel, ex);
  81. }
  82. finally
  83. {
  84. World.OnInternalLog(channel, "结束");
  85. World.Publish();
  86. }
  87. }
  88. public abstract List<T> Create();
  89. public abstract void Do(T obj);
  90. public override List<object> GetObjects()
  91. {
  92. return Objects.OfType<object>().ToList();
  93. }
  94. }
  95. public abstract class DeviceSystem<T> : SystemBase<T> where T : EntityEx<Device>
  96. {
  97. public override List<T> Create()
  98. {
  99. var t = typeof(T);
  100. while (true)
  101. {
  102. if (t.IsGenericType) break;
  103. t = t.BaseType;
  104. }
  105. var types = t.GetGenericArguments();
  106. var list = Device.All.Where(v => types.All(v.HasProtocol)).Where(Select).Select(v => Activator.CreateInstance(typeof(T), v, World)).OfType<T>().ToList();//此时才实例化Protocol
  107. if (list.Count == 0)
  108. {
  109. //throw new Exception($"{this.GetType().Name}未匹配到任何Device");
  110. }
  111. return list;
  112. }
  113. /// <summary>
  114. /// 筛选出需要实例化Protocol的Device
  115. /// </summary>
  116. /// <param name="dev"></param>
  117. /// <returns></returns>
  118. public abstract bool Select(Device dev);
  119. //public abstract List<Device> CreateDevices();
  120. }
  121. public abstract class ServiceSystem<T, TR> : SystemBase
  122. {
  123. private ConcurrentQueue<Action<List<WorkTimes>>> Actions = new ConcurrentQueue<Action<List<WorkTimes>>>();
  124. public TR Invoke(T obj)
  125. {
  126. var flag = false;
  127. TR result = default(TR);
  128. Actions.Enqueue(list =>
  129. {
  130. var sw = new Stopwatch();
  131. sw.Start();
  132. try
  133. {
  134. result = InvokeDo(obj);
  135. }
  136. finally
  137. {
  138. sw.Stop();
  139. list.AddSafe(new WorkTimes { Key = $"{obj?.ToString()}", Total = sw.ElapsedMilliseconds });
  140. flag = true;
  141. }
  142. });
  143. SpinWait.SpinUntil(() => flag);
  144. return result;
  145. }
  146. protected abstract TR Do(T obj);
  147. public override List<object> GetObjects()
  148. {
  149. return new List<object>();
  150. }
  151. public override void Update(List<WorkTimes> list)
  152. {
  153. while (Actions.TryDequeue(out var act))
  154. {
  155. act(list);
  156. }
  157. }
  158. private TR InvokeDo(T obj)
  159. {
  160. var channel = new Channel
  161. {
  162. World = World.Description,
  163. Stage = "DoLogics",
  164. System = Description,
  165. Item = obj.ToString()
  166. };
  167. try
  168. {
  169. Ltc.SetChannel(channel);
  170. World.OnInternalLog(channel, "开始");
  171. return Do(obj);
  172. }
  173. catch (Exception ex)
  174. {
  175. throw;
  176. }
  177. finally
  178. {
  179. World.OnInternalLog(channel, "结束");
  180. World.Publish();
  181. }
  182. }
  183. }
  184. public abstract class ServiceSystem<T> : SystemBase
  185. {
  186. private ConcurrentQueue<Action<List<WorkTimes>>> Actions = new ConcurrentQueue<Action<List<WorkTimes>>>();
  187. public void Invoke(T obj)
  188. {
  189. Actions.Enqueue(list =>
  190. {
  191. var sw = new Stopwatch();
  192. sw.Start();
  193. try
  194. {
  195. InvokeDo(obj);
  196. }
  197. finally
  198. {
  199. sw.Stop();
  200. list.AddSafe(new WorkTimes { Key = $"{obj?.ToString()}", Total = sw.ElapsedMilliseconds });
  201. }
  202. });
  203. }
  204. protected abstract void Do(T obj);
  205. private void InvokeDo(T obj)
  206. {
  207. var channel = new Channel
  208. {
  209. World = World.Description,
  210. Stage = "DoLogics",
  211. System = Description,
  212. Item = obj.ToString()
  213. };
  214. try
  215. {
  216. Ltc.SetChannel(channel);
  217. World.OnInternalLog(channel, "开始");
  218. Do(obj);
  219. }
  220. catch (Exception ex)
  221. {
  222. throw;
  223. }
  224. finally
  225. {
  226. World.OnInternalLog(channel, "结束");
  227. World.Publish();
  228. }
  229. }
  230. public override List<object> GetObjects()
  231. {
  232. return new List<object>();
  233. }
  234. public override void Update(List<WorkTimes> list)
  235. {
  236. while (Actions.TryDequeue(out var act))
  237. {
  238. act(list);
  239. }
  240. }
  241. }
  242. }