System.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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))
  107. .Where(Select)
  108. .Select(v => Activator.CreateInstance(typeof(T), v, World)).OfType<T>().ToList();//此时才实例化Protocol
  109. if (list.Count == 0)
  110. {
  111. //throw new Exception($"{this.GetType().Name}未匹配到任何Device");
  112. }
  113. return list;
  114. }
  115. /// <summary>
  116. /// 筛选出需要实例化Protocol的Device
  117. /// </summary>
  118. /// <param name="dev"></param>
  119. /// <returns></returns>
  120. public abstract bool Select(Device dev);
  121. //public abstract List<Device> CreateDevices();
  122. }
  123. public abstract class ServiceSystem<T, TR> : SystemBase
  124. {
  125. private ConcurrentQueue<Action<List<WorkTimes>>> Actions = new ConcurrentQueue<Action<List<WorkTimes>>>();
  126. public TR Invoke(T obj)
  127. {
  128. var flag = false;
  129. TR result = default(TR);
  130. Actions.Enqueue(list =>
  131. {
  132. var sw = new Stopwatch();
  133. sw.Start();
  134. try
  135. {
  136. result = InvokeDo(obj);
  137. }
  138. finally
  139. {
  140. sw.Stop();
  141. list.AddSafe(new WorkTimes { Key = $"{obj?.ToString()}", Total = sw.ElapsedMilliseconds });
  142. flag = true;
  143. }
  144. });
  145. SpinWait.SpinUntil(() => flag);
  146. return result;
  147. }
  148. protected abstract TR Do(T obj);
  149. public override List<object> GetObjects()
  150. {
  151. return new List<object>();
  152. }
  153. public override void Update(List<WorkTimes> list)
  154. {
  155. while (Actions.TryDequeue(out var act))
  156. {
  157. act(list);
  158. }
  159. }
  160. private TR InvokeDo(T obj)
  161. {
  162. var channel = new Channel
  163. {
  164. World = World.Description,
  165. Stage = "DoLogics",
  166. System = Description,
  167. Item = obj.ToString()
  168. };
  169. try
  170. {
  171. Ltc.SetChannel(channel);
  172. World.OnInternalLog(channel, "开始");
  173. return Do(obj);
  174. }
  175. catch (Exception ex)
  176. {
  177. throw;
  178. }
  179. finally
  180. {
  181. World.OnInternalLog(channel, "结束");
  182. World.Publish();
  183. }
  184. }
  185. }
  186. public abstract class ServiceSystem<T> : SystemBase
  187. {
  188. private ConcurrentQueue<Action<List<WorkTimes>>> Actions = new ConcurrentQueue<Action<List<WorkTimes>>>();
  189. public void Invoke(T obj)
  190. {
  191. Actions.Enqueue(list =>
  192. {
  193. var sw = new Stopwatch();
  194. sw.Start();
  195. try
  196. {
  197. InvokeDo(obj);
  198. }
  199. finally
  200. {
  201. sw.Stop();
  202. list.AddSafe(new WorkTimes { Key = $"{obj?.ToString()}", Total = sw.ElapsedMilliseconds });
  203. }
  204. });
  205. }
  206. protected abstract void Do(T obj);
  207. private void InvokeDo(T obj)
  208. {
  209. var channel = new Channel
  210. {
  211. World = World.Description,
  212. Stage = "DoLogics",
  213. System = Description,
  214. Item = obj.ToString()
  215. };
  216. try
  217. {
  218. Ltc.SetChannel(channel);
  219. World.OnInternalLog(channel, "开始");
  220. Do(obj);
  221. }
  222. catch (Exception ex)
  223. {
  224. throw;
  225. }
  226. finally
  227. {
  228. World.OnInternalLog(channel, "结束");
  229. World.Publish();
  230. }
  231. }
  232. public override List<object> GetObjects()
  233. {
  234. return new List<object>();
  235. }
  236. public override void Update(List<WorkTimes> list)
  237. {
  238. while (Actions.TryDequeue(out var act))
  239. {
  240. act(list);
  241. }
  242. }
  243. }
  244. }