using Pms.DataLibrary.Order; using Pms.Models; using ProjectManagementSystem.Common.Extenions; using ProjectManagementSystem.Common.Logger; using ProjectManagementSystem.Common.WebApi; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ProjectManagementSystem.Common.Core { public class TaskBehavior { private static TaskBehavior m_instance; private static ConcurrentDictionary tempLog = new ConcurrentDictionary(); public static ConcurrentDictionary BehaviorDict { get; set; } = new ConcurrentDictionary(); public static ConcurrentDictionary PmsBehaviorLoopDict { get; set; } = new ConcurrentDictionary(); public static TaskBehavior Instance { get { if (m_instance == null) { m_instance = new TaskBehavior(); if (!m_instance.Initialize()) { m_instance = null; } } return m_instance; } } private TaskBehavior() { } private static bool CheckLogRepeat(string taskId, string log) { bool result = tempLog.ContainsKey(taskId) ? tempLog[taskId] == log : false; tempLog.AddOrUpdate(taskId, log, (key, vaule) => log); return result; } public static void Log(TaskData taskData, StepData stepData, string log) { string strLog = $"{taskData.TaskID} Step{taskData.CurrentStepID} {stepData.PmsBehavior} {stepData.AgvBehavior} {taskData.Carrier}# {stepData.WareHouseID} {log}"; if (CheckLogRepeat(taskData.TaskID, log)) return; CLog.Instance.GetAgvLog(taskData.Carrier).WriteInfo(strLog); } public static void RemoveTempLog(string taskId) { if (string.IsNullOrEmpty(taskId)) return; tempLog.TryRemove(taskId, out string _); } public static string GetTempLog(string taskId) { if (string.IsNullOrEmpty(taskId)) return null; return tempLog.ContainsKey(taskId) ? tempLog[taskId] : null; } private bool Initialize() { try { Task.Factory.StartNew(UserThread); return true; } catch (Exception ex) { CLog.Instance.SystemLog.WriteException("TaskBehavior Initialize", ex); } return false; } private void ProcessPmsBehavior() { DateTime start = DateTime.Now; var dataDict = PmsApi.GetPmsBehavior(); if (dataDict == null || dataDict.Count == 0) return; var taskList = PmsApi.GetTaskList(); if (taskList == null || taskList.Count == 0) return; Parallel.ForEach(dataDict.Values, data => { try { if (!BehaviorDict.ContainsKey(data.PmsBehavior)) return; //获取任务数据 var taskData = taskList.FirstOrDefault(d => d.TaskID == data.TaskId); if (taskData == null) return; var stepList = PmsApi.GetStepList(data.TaskId); if (stepList == null) return; taskData.StepList = stepList; var stepData = taskData.GetCurrentStepInfo(); if (stepData == null) return; if (stepData.PmsBehavior != data.PmsBehavior) return; var taskApiTimeSpan = (DateTime.Now - start).TotalMilliseconds; //执行PMS行为码 DateTime start3 = DateTime.Now; bool result = BehaviorDict[data.PmsBehavior].TaskBookOperator(taskData, stepData); var operatorTimeSpan = (DateTime.Now - start3).TotalMilliseconds; //上报PMS行为码 if (result) { bool setResult = PmsApi.SetPmsBehaviorFinish(data.TaskId, taskData.Carrier, data.PmsBehavior); var totalTimeSpan = (DateTime.Now - start).TotalMilliseconds; CLog.Instance.GetAgvLog(taskData.Carrier).WriteDebug($"{data.TaskId} Step{taskData.CurrentStepID} {data.PmsBehavior} {data.agvId}# PMS行为码完成上报{setResult.ToChineseString()}" + $" 耗时: {taskApiTimeSpan:F1}ms {operatorTimeSpan:F1}ms 总耗时:{totalTimeSpan:F1}ms"); } } catch (Exception ex) { CLog.Instance.SystemLog.WriteExceptionCaller(ex); } }); } private void ProcessPmsBehaviorTask() { //独立线程执行 var dataDict = PmsApi.GetPmsBehavior(); if (dataDict == null || dataDict.Count == 0) return; var dataDictValues = dataDict.Values.ToArray(); foreach (var item in dataDictValues) { if (!BehaviorDict.ContainsKey(item.PmsBehavior)) continue; if (!PmsBehaviorLoopDict.ContainsKey(item.agvId)) { PmsBehaviorLoop loop = new PmsBehaviorLoop(); loop.BehavoirInfo = item; loop.Start(); PmsBehaviorLoopDict.AddOrUpdate(loop.AgvId, loop, (key, value) => loop); } else { var loop = PmsBehaviorLoopDict[item.agvId]; if (!loop.IsStart) { loop.BehavoirInfo = item; loop.Start(); } } } } private void UserThread() { CLog.Instance.SystemLog.WriteDebug($"TaskBehavior已启动"); while (true) { try { ProcessPmsBehaviorTask(); } catch (Exception ex) { CLog.Instance.SystemLog.WriteException("TaskBehavior", ex); Thread.Sleep(5000); } Thread.Sleep(100); } } } public class PmsBehaviorLoop { public int AgvId { get { return BehavoirInfo.agvId; } } public bool IsStart { get; set; } public RequestPmsTaskInfo BehavoirInfo { get; set; } public PmsBehaviorLoop() { } public void Start() { IsStart = true; Task.Factory.StartNew(UserThread); } private bool Process() { DateTime start = DateTime.Now; var dataDict = PmsApi.GetPmsBehavior(); if (dataDict == null) { LogDebug("获取所有PMS行为码失败"); return true; } if (dataDict.Count == 0) { LogDebug("获取所有PMS行为码数量为0"); return true; } var find = dataDict.Values.FirstOrDefault(d => d.TaskId == BehavoirInfo.TaskId && d.PmsBehavior == BehavoirInfo.PmsBehavior && d.agvId == BehavoirInfo.agvId); if (find == null) { LogDebug("未找到当前PMS行为码"); return true; } //获取任务数据 var taskData = PmsApi.GetTaskData(BehavoirInfo.TaskId); if (taskData == null) { LogDebug("获取当前任务失败"); return true; } var stepData = taskData.GetCurrentStepInfo(); if (stepData == null) { LogDebug("获取当前任务StepData失败"); return true; } if (stepData.PmsBehavior != BehavoirInfo.PmsBehavior) { LogDebug($"PMS行为码不匹配,当前任务Step{taskData.CurrentStepID} {stepData.PmsBehavior}"); return true; } var taskApiTimeSpan = (DateTime.Now - start).TotalMilliseconds; //执行PMS行为码 DateTime start3 = DateTime.Now; bool result = TaskBehavior.BehaviorDict[BehavoirInfo.PmsBehavior].TaskBookOperator(taskData, stepData); var operatorTimeSpan = (DateTime.Now - start3).TotalMilliseconds; //上报PMS行为码 if (result) { bool setResult = PmsApi.SetPmsBehaviorFinish(BehavoirInfo.TaskId, taskData.Carrier, BehavoirInfo.PmsBehavior); var totalTimeSpan = (DateTime.Now - start).TotalMilliseconds; CLog.Instance.GetAgvLog(taskData.Carrier).WriteDebug($"{BehavoirInfo.TaskId} Step{taskData.CurrentStepID} {BehavoirInfo.PmsBehavior} {BehavoirInfo.agvId}# PMS行为码完成上报{setResult.ToChineseString()}" + $" 耗时: {taskApiTimeSpan:F1}ms {operatorTimeSpan:F1}ms 总耗时:{totalTimeSpan:F1}ms"); return setResult; } return false; } private void LogDebug(string log) { CLog.Instance.GetAgvLog(BehavoirInfo.agvId).WriteDebug($"{BehavoirInfo.TaskId} {BehavoirInfo.PmsBehavior} {BehavoirInfo.agvId}# {log}"); } private void UserThread() { LogDebug("PmsBehaviorLoop已启动"); while (IsStart) { bool processResult = false; try { processResult = Process(); if (processResult) { TaskBehavior.RemoveTempLog(BehavoirInfo.TaskId); } } catch (Exception ex) { CLog.Instance.SystemLog.WriteException("PmsBehaviorLoop", ex); Thread.Sleep(5000); //抛异常退出循环 processResult = true; } if (processResult) { break; } Thread.Sleep(100); } LogDebug("PmsBehaviorLoop已退出"); IsStart = false; } } public abstract class BaseTaskBookBehaviorV2 { public int Behavior { get; set; } public string Remark { get; set; } public BaseTaskBookBehaviorV2(int behavior, string remark) { Behavior = behavior; Remark = remark; TaskBehavior.BehaviorDict.AddOrUpdate(Behavior, this, (key, value) => this); } public abstract bool TaskBookOperator(TaskData taskData, StepData stepData); public void Log(TaskData taskData, StepData stepData, string log) { TaskBehavior.Log(taskData, stepData, log); } public void LogException(Exception ex) { CLog.Instance.TaskLog.WriteException("TaskBookBehavior", ex); } } }