CTaskEventBase.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. using DbCommon.BusinessCore.BaseCore;
  2. using ProjectManagementSystem.Common.Models.Crms;
  3. using ProjectManagementSystem.Common.Config;
  4. using ProjectManagementSystem.Common.Extenions;
  5. using ProjectManagementSystem.Common.Logger;
  6. using ProjectManagementSystem.Common.Service;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using ProjectManagementSystem.Common.Function;
  14. namespace ProjectManagementSystem.Common.Core
  15. {
  16. public abstract class CTaskEventBase
  17. {
  18. private int processInterval = 1000;
  19. private Dictionary<string, TaskData> TaskDataDict { get; set; } = new Dictionary<string, TaskData>();
  20. private List<ICustomProcess> taskProcesses = new List<ICustomProcess>();
  21. private Dictionary<int, ResultAgvData> agvDataDict = new Dictionary<int, ResultAgvData>();
  22. public CTaskEventBase()
  23. {
  24. var assemblyName = this.GetType().Assembly.GetName().Name;
  25. var nameSpace = this.GetType().Namespace;
  26. var processArray = Common.Function.AppSetting.TryGetValue<string>("TaskProcess").ToValueArray<string>();
  27. foreach (var item in processArray)
  28. {
  29. string fullClassName = $"{nameSpace}.{item}";
  30. var processObj = Common.Function.InstanceConstructor.GetInstance<ICustomProcess>(assemblyName, fullClassName);
  31. if (processObj != null)
  32. {
  33. taskProcesses.Add(processObj);
  34. }
  35. }
  36. var interval = AppSetting.TryGetValue<int>("TaskProcessInterval");
  37. if (interval > 0)
  38. {
  39. processInterval = interval;
  40. }
  41. Task.Factory.StartNew(TaskThread, TaskCreationOptions.LongRunning);
  42. if (taskProcesses.Count > 0)
  43. {
  44. Task.Factory.StartNew(CustomThread, TaskCreationOptions.LongRunning);
  45. }
  46. }
  47. private void TaskEventProc()
  48. {
  49. var taskDataList = Crms.PmsApi.GetTaskDataList();
  50. if (taskDataList == null) return;
  51. var agvDataList = Crms.PmsApi.GetAllCarrier();
  52. if (agvDataList == null) return;
  53. AgvDataProc(taskDataList, agvDataList);
  54. TaskStateProc(taskDataList);
  55. TaskCustomProc(taskDataList);
  56. }
  57. private void CustomProc()
  58. {
  59. var taskDataList = Crms.PmsApi.GetTaskDataList();
  60. if (taskDataList == null) return;
  61. for (int i = 0; i < taskProcesses.Count; i++)
  62. {
  63. taskProcesses[i].CustomProcess(taskDataList);
  64. }
  65. }
  66. private void AgvDataProc(List<TaskData> taskDataList, List<ResultAgvData> agvDataList)
  67. {
  68. //AGV数据的记录
  69. for (int i = 0; i < agvDataList.Count; i++)
  70. {
  71. var agvData = agvDataList[i];
  72. bool record = false;
  73. if (!agvDataDict.TryGetValue(agvData.AgvID, out var lastAgvData))
  74. {
  75. agvDataDict.Add(agvData.AgvID, agvData);
  76. record = true;
  77. }
  78. else
  79. {
  80. if (agvData.Online != lastAgvData.Online
  81. || agvData.GraphEdge != lastAgvData.GraphEdge
  82. || agvData.GraphVertex != lastAgvData.GraphVertex
  83. || agvData.LogicBits != lastAgvData.LogicBits)
  84. {
  85. record = true;
  86. }
  87. agvDataDict[agvData.AgvID] = agvData;
  88. }
  89. if (record)
  90. {
  91. string stepString = taskDataList.FirstOrDefault(d => d.TaskState > ETaskState.None && d.Carrier == agvData.AgvID)?.GetCurrentStepInfo()?.ToSimpleString();
  92. CLog.Instance.GetAgvLog(agvData.AgvID).WriteDebug($"{stepString}【{agvData.ToSimpleString()}】");
  93. }
  94. }
  95. }
  96. private void TaskStateProc(List<TaskData> taskDataList)
  97. {
  98. // 当前任务更新到缓存
  99. foreach (var taskData in taskDataList)
  100. {
  101. int agvID = taskData.Carrier > 0 ? taskData.Carrier : taskData.BindingAGVNumber;
  102. bool recordStep = false;
  103. if (!TaskDataDict.TryGetValue(taskData.ID, out var lastTaskInfo))
  104. {
  105. if (taskData.TaskState > ETaskState.None)
  106. {
  107. TaskDataDict.Add(taskData.ID, taskData);
  108. CLog.Instance.GetAgvLog(agvID).WriteDebug($"{taskData.TaskID} 任务状态{taskData.TaskState}(添加记录) {taskData.ID} {taskData.ToSimpleString()}");
  109. recordStep = true;
  110. }
  111. }
  112. else
  113. {
  114. if (lastTaskInfo.TaskState != taskData.TaskState)
  115. {
  116. //CLog.Instance.GetAgvLog(agvID).WriteDebug($"{taskData.TaskID} 运行状态改变 {lastTaskInfo.TaskState} => {taskData.TaskState}");
  117. TaskStateChanged(taskData, lastTaskInfo);
  118. }
  119. var lastStepInfo = lastTaskInfo.GetCurrentStepInfo();
  120. var stepInfo = taskData.GetCurrentStepInfo();
  121. if (stepInfo != null
  122. && (lastStepInfo?.TemplateStepID != stepInfo.TemplateStepID
  123. || lastStepInfo?.SystemStepState != stepInfo.SystemStepState))
  124. {
  125. recordStep = true;
  126. }
  127. TaskDataDict[taskData.ID] = taskData;
  128. }
  129. if (recordStep)
  130. {
  131. string stepString = taskData.GetCurrentStepInfo()?.ToSimpleString();
  132. agvDataDict.TryGetValue(taskData.Carrier, out ResultAgvData agvData);
  133. string agvString = agvData?.ToSimpleString();
  134. if (!string.IsNullOrEmpty(stepString)
  135. || !string.IsNullOrEmpty(agvString))
  136. {
  137. CLog.Instance.GetAgvLog(agvID).WriteDebug($"{stepString}【{agvString}】");
  138. }
  139. }
  140. }
  141. //获取历史任务对比
  142. if (TaskDataDict.Count == 0) { return; }
  143. string[] taskIdArray = TaskDataDict.Keys.Where(d => !taskDataList.Exists(s => s.ID == d)).ToArray();
  144. foreach (string id in taskIdArray)
  145. {
  146. var taskDataLast = TaskDataDict[id];
  147. var taskData = Crms.PmsApi.GetHistoryTask(taskDataLast.TaskID);
  148. if (taskData != null
  149. && taskData.ID == id)
  150. {
  151. if (taskData.StepList == null)
  152. {
  153. taskData.StepList = taskDataLast.StepList;
  154. }
  155. CLog.Instance.GetAgvLog(taskData.Carrier).WriteDebug($"{taskData.TaskID} 任务状态{taskData.TaskState}(移除记录) {id} Count={taskIdArray.Length}");
  156. TaskDataDict.Remove(id);
  157. switch (taskData.TaskState)
  158. {
  159. case ETaskState.Finished:
  160. TaskFinished(taskData);
  161. break;
  162. case ETaskState.Canceled:
  163. TaskCanceled(taskData);
  164. break;
  165. case ETaskState.TerminateTask:
  166. TaskTerminated(taskData);
  167. break;
  168. case ETaskState.Exceptioned:
  169. TaskExceptioned(taskData);
  170. break;
  171. case ETaskState.RecoveryException:
  172. break;
  173. default:
  174. TaskBecomeHistory(taskData);
  175. break;
  176. }
  177. }
  178. else
  179. {
  180. if (taskDataLast.ExpectedEndTime == null || taskDataLast.ExpectedEndTime == DateTime.MinValue)
  181. {
  182. taskDataLast.ExpectedEndTime = DateTime.Now;
  183. }
  184. if ((DateTime.Now - (taskDataLast.ExpectedEndTime ?? DateTime.MinValue)).TotalSeconds > 10)
  185. {
  186. CLog.Instance.GetAgvLog(taskDataLast.Carrier).WriteDebug($"{taskDataLast.TaskID} 获取历史任务失败(移除记录) {id} Count={taskIdArray.Length}");
  187. TaskDataDict.Remove(id);
  188. }
  189. }
  190. }
  191. }
  192. public void TaskThread()
  193. {
  194. CLog.Instance.SystemLog.WriteDebug($"CTaskEvent已启动");
  195. while (true)
  196. {
  197. try
  198. {
  199. TaskEventProc();
  200. }
  201. catch (Exception ex)
  202. {
  203. CLog.Instance.TaskLog.WriteException("TaskEvent", ex);
  204. Thread.Sleep(5000);
  205. }
  206. Thread.Sleep(1000);
  207. }
  208. }
  209. public void CustomThread()
  210. {
  211. CLog.Instance.SystemLog.WriteDebug($"CustomProc已启动");
  212. while (true)
  213. {
  214. try
  215. {
  216. CustomProc();
  217. }
  218. catch (Exception ex)
  219. {
  220. CLog.Instance.TaskLog.WriteException("CustomProc", ex);
  221. Thread.Sleep(5000);
  222. }
  223. Thread.Sleep(processInterval);
  224. }
  225. }
  226. public abstract void TaskCustomProc(List<TaskData> taskDataList);
  227. public abstract void TaskStateChanged(TaskData currentTaskInfo, TaskData lastTaskInfo);
  228. public abstract void TaskFinished(TaskData taskInfo);
  229. public abstract void TaskExceptioned(TaskData taskInfo);
  230. public abstract void TaskCanceled(TaskData taskInfo);
  231. public abstract void TaskTerminated(TaskData taskInfo);
  232. public abstract void TaskBecomeHistory(TaskData taskInfo);
  233. }
  234. public interface ICustomProcess
  235. {
  236. void CustomProcess(List<TaskData> taskDataList);
  237. }
  238. }