System.cs 7.7 KB

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