using DbCommon.BusinessCore.BaseCore; using ProjectManagementSystem.Common.Models.Crms; using ProjectManagementSystem.Common.Config; using ProjectManagementSystem.Common.Extenions; using ProjectManagementSystem.Common.Logger; using ProjectManagementSystem.Common.Service; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using ProjectManagementSystem.Common.Function; namespace ProjectManagementSystem.Common.Core { public abstract class CTaskEventBase { private int processInterval = 1000; private Dictionary TaskDataDict { get; set; } = new Dictionary(); private List taskProcesses = new List(); private Dictionary agvDataDict = new Dictionary(); public CTaskEventBase() { var assemblyName = this.GetType().Assembly.GetName().Name; var nameSpace = this.GetType().Namespace; var processArray = Common.Function.AppSetting.TryGetValue("TaskProcess").ToValueArray(); foreach (var item in processArray) { string fullClassName = $"{nameSpace}.{item}"; var processObj = Common.Function.InstanceConstructor.GetInstance(assemblyName, fullClassName); if (processObj != null) { taskProcesses.Add(processObj); } } var interval = AppSetting.TryGetValue("TaskProcessInterval"); if (interval > 0) { processInterval = interval; } Task.Factory.StartNew(TaskThread, TaskCreationOptions.LongRunning); if (taskProcesses.Count > 0) { Task.Factory.StartNew(CustomThread, TaskCreationOptions.LongRunning); } } private void TaskEventProc() { var taskDataList = Crms.PmsApi.GetTaskDataList(); if (taskDataList == null) return; var agvDataList = Crms.PmsApi.GetAllCarrier(); if (agvDataList == null) return; AgvDataProc(taskDataList, agvDataList); TaskStateProc(taskDataList); TaskCustomProc(taskDataList); } private void CustomProc() { var taskDataList = Crms.PmsApi.GetTaskDataList(); if (taskDataList == null) return; for (int i = 0; i < taskProcesses.Count; i++) { taskProcesses[i].CustomProcess(taskDataList); } } private void AgvDataProc(List taskDataList, List agvDataList) { //AGV数据的记录 for (int i = 0; i < agvDataList.Count; i++) { var agvData = agvDataList[i]; bool record = false; if (!agvDataDict.TryGetValue(agvData.AgvID, out var lastAgvData)) { agvDataDict.Add(agvData.AgvID, agvData); record = true; } else { if (agvData.Online != lastAgvData.Online || agvData.GraphEdge != lastAgvData.GraphEdge || agvData.GraphVertex != lastAgvData.GraphVertex || agvData.LogicBits != lastAgvData.LogicBits) { record = true; } agvDataDict[agvData.AgvID] = agvData; } if (record) { string stepString = taskDataList.FirstOrDefault(d => d.TaskState > ETaskState.None && d.Carrier == agvData.AgvID)?.GetCurrentStepInfo()?.ToSimpleString(); CLog.Instance.GetAgvLog(agvData.AgvID).WriteDebug($"{stepString}【{agvData.ToSimpleString()}】"); } } } private void TaskStateProc(List taskDataList) { // 当前任务更新到缓存 foreach (var taskData in taskDataList) { int agvID = taskData.Carrier > 0 ? taskData.Carrier : taskData.BindingAGVNumber; bool recordStep = false; if (!TaskDataDict.TryGetValue(taskData.ID, out var lastTaskInfo)) { if (taskData.TaskState > ETaskState.None) { TaskDataDict.Add(taskData.ID, taskData); CLog.Instance.GetAgvLog(agvID).WriteDebug($"{taskData.TaskID} 任务状态{taskData.TaskState}(添加记录) {taskData.ID} {taskData.ToSimpleString()}"); recordStep = true; } } else { if (lastTaskInfo.TaskState != taskData.TaskState) { //CLog.Instance.GetAgvLog(agvID).WriteDebug($"{taskData.TaskID} 运行状态改变 {lastTaskInfo.TaskState} => {taskData.TaskState}"); TaskStateChanged(taskData, lastTaskInfo); } var lastStepInfo = lastTaskInfo.GetCurrentStepInfo(); var stepInfo = taskData.GetCurrentStepInfo(); if (stepInfo != null && (lastStepInfo?.TemplateStepID != stepInfo.TemplateStepID || lastStepInfo?.SystemStepState != stepInfo.SystemStepState)) { recordStep = true; } TaskDataDict[taskData.ID] = taskData; } if (recordStep) { string stepString = taskData.GetCurrentStepInfo()?.ToSimpleString(); agvDataDict.TryGetValue(taskData.Carrier, out ResultAgvData agvData); string agvString = agvData?.ToSimpleString(); if (!string.IsNullOrEmpty(stepString) || !string.IsNullOrEmpty(agvString)) { CLog.Instance.GetAgvLog(agvID).WriteDebug($"{stepString}【{agvString}】"); } } } //获取历史任务对比 if (TaskDataDict.Count == 0) { return; } string[] taskIdArray = TaskDataDict.Keys.Where(d => !taskDataList.Exists(s => s.ID == d)).ToArray(); foreach (string id in taskIdArray) { var taskDataLast = TaskDataDict[id]; var taskData = Crms.PmsApi.GetHistoryTask(taskDataLast.TaskID); if (taskData != null && taskData.ID == id) { if (taskData.StepList == null) { taskData.StepList = taskDataLast.StepList; } CLog.Instance.GetAgvLog(taskData.Carrier).WriteDebug($"{taskData.TaskID} 任务状态{taskData.TaskState}(移除记录) {id} Count={taskIdArray.Length}"); TaskDataDict.Remove(id); switch (taskData.TaskState) { case ETaskState.Finished: TaskFinished(taskData); break; case ETaskState.Canceled: TaskCanceled(taskData); break; case ETaskState.TerminateTask: TaskTerminated(taskData); break; case ETaskState.Exceptioned: TaskExceptioned(taskData); break; case ETaskState.RecoveryException: break; default: TaskBecomeHistory(taskData); break; } } else { if (taskDataLast.ExpectedEndTime == null || taskDataLast.ExpectedEndTime == DateTime.MinValue) { taskDataLast.ExpectedEndTime = DateTime.Now; } if ((DateTime.Now - (taskDataLast.ExpectedEndTime ?? DateTime.MinValue)).TotalSeconds > 10) { CLog.Instance.GetAgvLog(taskDataLast.Carrier).WriteDebug($"{taskDataLast.TaskID} 获取历史任务失败(移除记录) {id} Count={taskIdArray.Length}"); TaskDataDict.Remove(id); } } } } public void TaskThread() { CLog.Instance.SystemLog.WriteDebug($"CTaskEvent已启动"); while (true) { try { TaskEventProc(); } catch (Exception ex) { CLog.Instance.TaskLog.WriteException("TaskEvent", ex); Thread.Sleep(5000); } Thread.Sleep(1000); } } public void CustomThread() { CLog.Instance.SystemLog.WriteDebug($"CustomProc已启动"); while (true) { try { CustomProc(); } catch (Exception ex) { CLog.Instance.TaskLog.WriteException("CustomProc", ex); Thread.Sleep(5000); } Thread.Sleep(processInterval); } } public abstract void TaskCustomProc(List taskDataList); public abstract void TaskStateChanged(TaskData currentTaskInfo, TaskData lastTaskInfo); public abstract void TaskFinished(TaskData taskInfo); public abstract void TaskExceptioned(TaskData taskInfo); public abstract void TaskCanceled(TaskData taskInfo); public abstract void TaskTerminated(TaskData taskInfo); public abstract void TaskBecomeHistory(TaskData taskInfo); } public interface ICustomProcess { void CustomProcess(List taskDataList); } }