using Furion.Logging; using Microsoft.AspNetCore.SignalR; namespace WCS.Application; public static class PLCTaskAction { //服务运行状态 public static bool boRunningState = false; private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId); private static List listPlc; private static List listPlcDevice; private static List listPlcStation; private static List listPlcUtil = new List(); private static CancellationTokenSource cts;//取消线程标识 public static event EventHandler DeviceValueChangeEvent; static PLCTaskAction() { //订阅事件 DeviceValueChangeEvent += PLCService.OnChangeEvent; listPlc = _db.Queryable().ToList(); listPlcDevice = _db.Queryable().ToList(); listPlcStation = _db.Queryable().ToList(); } /// /// 初始化PLC连接 /// public static void Init() { if (listPlcUtil.Count != 0) { cts.Cancel(); listPlc = _db.Queryable().ToList(); listPlcDevice = _db.Queryable().ToList(); listPlcStation = _db.Queryable().ToList(); //等待几秒钟,把已有线程取消掉再连接 Thread.Sleep(5000); foreach (var modPlcUtil in listPlcUtil) { modPlcUtil.Close(); } listPlcUtil.Clear(); } foreach (var modPlc in listPlc) { var plc = new PLCUtil(modPlc); listPlcUtil.Add(plc); } cts = new CancellationTokenSource(); boRunningState = true; StartRead(); } /// /// 开启读取plc线程 /// public static void StartRead() { foreach (var modPlc in listPlc) { Task.Run(() => { var _modplc = modPlc; while (true) { //取消线程 关闭PLC连接 if (cts.Token.IsCancellationRequested) { foreach (var modPlcUtil in listPlcUtil) { modPlcUtil.Close(); } throw new OperationCanceledException(); } try { var modPlcUtil = listPlcUtil.FirstOrDefault(s => s.PlcId == modPlc.Id); if (modPlcUtil == null) { modPlcUtil = new PLCUtil(modPlc); listPlcUtil.Add(modPlcUtil); } var listDevice = listPlcDevice.Where(s => s.PlcId == _modplc.Id).ToList(); //循环读设备 foreach (var modDevice in listDevice.Where(s => s.Level == DeviceLevelEnum.DB)) { var (result, value) = modPlcUtil.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.PlcPos); if (result.IsSucceed) { //无流程跳出 if (value == 0) continue; var dto = modDevice.Adapt(); dto.Value = value; dto.Type = _modplc.Type; dto.PLCUtil = modPlcUtil; dto.listStation = listPlcStation.Where(s => s.DeviceId == modDevice.Id).ToList(); dto.listDevice = listDevice.Where(s => s.StationNum == modDevice.StationNum).ToList(); //这里触发值变更事件 DeviceValueChangeEvent?.Invoke(dto, EventArgs.Empty); } else { //删除当前连接 下一次循环重新连接 Console.WriteLine("连接断开..."); modPlcUtil.Close(); listPlcUtil.Remove(modPlcUtil); } } Thread.Sleep(3000); } catch (OperationCanceledException) { Console.WriteLine("中止线程"); } catch (Exception ex) { Log.Error(ex.Message, ex); } } }, cts.Token); } } /// /// 停止服务 /// public static void Stop() { cts.Cancel(); boRunningState = false; } }