diff --git a/RIZO.Admin.WebApi/PLC/Service/PlcService.cs b/RIZO.Admin.WebApi/PLC/Service/PlcService.cs index 75b5047..22385f6 100644 --- a/RIZO.Admin.WebApi/PLC/Service/PlcService.cs +++ b/RIZO.Admin.WebApi/PLC/Service/PlcService.cs @@ -368,14 +368,13 @@ namespace RIZO.Admin.WebApi.PLC.Service /// PLC生产数据读取核心方法(优化版) /// /// 成功状态/生产数据/提示消息 - public async Task<(bool Success, PlcProductionData Data, string Message)> ReadProductionDataAsync( + async Task<(bool Success, PlcProductionData Data, string Message)> ReadProductionDataAsync( string ip, string plcName, short rack, short slot, CpuType cpuType = CpuType.S71500) { - // 1. 参数校验(精简返回,直接判空返回) if (string.IsNullOrWhiteSpace(ip)) return (false, null, "PLC IP地址不能为空"); if (string.IsNullOrWhiteSpace(plcName)) return (false, null, "PLC名称不能为空"); if (rack is < 0 or > 10) return (false, null, $"PLC机架号{rack}无效(有效值0-10)"); @@ -389,61 +388,114 @@ namespace RIZO.Admin.WebApi.PLC.Service int iSaveRequest = 0; string strSaveRequest = string.Empty; - // 2. 并发控制(确保释放,外层无try) - await _concurrencySemaphore.WaitAsync(); + // 2. 并发控制,ConfigureAwait(false)减少线程上下文切换开销、提升异步执行效率 + await _concurrencySemaphore.WaitAsync().ConfigureAwait(false); try { - // 3. 连接池复用+有效性校验(精简逻辑,移除冗余变量) + + // 3. 连接池复用+有效性校验(精简逻辑+轻量提效) if (_plcConnPool.TryGetValue(poolKey, out var poolItem) && poolItem.Client is { IsConnected: true }) { plc = poolItem.Client; - _plcConnPool.TryUpdate(poolKey, (plc, DateTime.Now), poolItem); + _plcConnPool[poolKey] = (plc, DateTime.Now); isConnReused = true; } else { plc = CreatePlcClient(cpuType, ip, rack, slot); - await OpenPlcConnectionAsync(plc); + await OpenPlcConnectionAsync(plc).ConfigureAwait(false); if (!plc.IsConnected) return (false, null, $"{plcName}连接失败"); _plcConnPool.TryAdd(poolKey, (plc, DateTime.Now)); } - - // 4. 多工位请求状态读取(精简分支,保留原逻辑,移除冗余注释) - iQueryRequest = 0; - iSaveRequest = 0; - strSaveRequest = string.Empty; + #region 多工位请求状态读取 + //// 4. 多工位请求状态读取 + //switch (plcName) + //{ + // case "OP020-2": + // // 优化:异步读取取消上下文切换 + // iSaveRequest = await ReadPlcIntAsync(plc, _op020_2IntMap["上传请求"]).ConfigureAwait(false); + // break; + // case "OP020-3": + // iSaveRequest = 1; + // break; + // case "OP020-4": + // // 核心优化:4个地址并行读取(耗时从累加和→最长单地址耗时) + // var task4_1 = ReadPlcIntAsync(plc, _op020_4IntMap["产品1上传请求"]); + // var task4_2 = ReadPlcIntAsync(plc, _op020_4IntMap["产品2上传请求"]); + // var task4_3 = ReadPlcIntAsync(plc, _op020_4IntMap["产品3上传请求"]); + // var task4_4 = ReadPlcIntAsync(plc, _op020_4IntMap["产品4上传请求"]); + // // 并行等待所有任务完成(无编译错误) + // await Task.WhenAll(task4_1, task4_2, task4_3, task4_4).ConfigureAwait(false); + // iSaveRequest = (task4_1.Result == 1 || task4_2.Result == 1 || task4_3.Result == 1 || task4_4.Result == 1) ? 1 : 0; + // break; + // case "OP070-1": + // case "OP070-2": + // case "OP070-3": + // // 优化:2个地址并行读取 + // var taskQuery70 = ReadPlcIntAsync(plc, _op070_1IntMap["查询请求"]); + // var taskSave70 = ReadPlcIntAsync(plc, _op070_1IntMap["保存请求"]); + // await Task.WhenAll(taskQuery70, taskSave70).ConfigureAwait(false); + // iQueryRequest = taskQuery70.Result; + // iSaveRequest = taskSave70.Result; + // break; + // case "OP075": + // // 优化:2个地址并行读取 + // var taskQuery75 = ReadPlcIntAsync(plc, _op075IntMap["查询请求"]); + // var taskSave75 = ReadPlcIntAsync(plc, _op075IntMap["保存请求"]); + // await Task.WhenAll(taskQuery75, taskSave75).ConfigureAwait(false); + // iQueryRequest = taskQuery75.Result; + // iSaveRequest = taskSave75.Result; + // break; + // case "OP080-1": + // // 优化:3个地址并行读取 + // var taskQuery80 = ReadPlcIntAsync(plc, _op080_1IntMap["合装工位查询请求"]); + // var task8_1 = ReadPlcIntAsync(plc, _op080_1IntMap["合装结果保存请求"]); + // var task8_2 = ReadPlcIntAsync(plc, _op080_1IntMap["拧紧结果保存请求"]); + // await Task.WhenAll(taskQuery80, task8_1, task8_2).ConfigureAwait(false); + // iQueryRequest = taskQuery80.Result; + // if (task8_1.Result == 1) { iSaveRequest = 1; strSaveRequest = "合装结果保存请求"; } + // if (task8_2.Result == 1) + // { + // iSaveRequest = 1; + // strSaveRequest = string.IsNullOrEmpty(strSaveRequest) + // ? "拧紧结果保存请求" + // : $"{strSaveRequest},拧紧结果保存请求"; + // } + // break; + //} + #endregion + // 4. 多工位请求状态读取 switch (plcName) { case "OP020-2": - iSaveRequest = await ReadPlcIntAsync(plc, _op020_2IntMap["上传请求"]); + iSaveRequest = await ReadPlcIntAsync(plc, _op020_2IntMap["上传请求"]).ConfigureAwait(false); break; case "OP020-3": iSaveRequest = 1; break; case "OP020-4": - var s4_1 = await ReadPlcIntAsync(plc, _op020_4IntMap["产品1上传请求"]); - var s4_2 = await ReadPlcIntAsync(plc, _op020_4IntMap["产品2上传请求"]); - var s4_3 = await ReadPlcIntAsync(plc, _op020_4IntMap["产品3上传请求"]); - var s4_4 = await ReadPlcIntAsync(plc, _op020_4IntMap["产品4上传请求"]); - iSaveRequest = (s4_1 == 1 || s4_2 == 1 || s4_3 == 1 || s4_4 == 1) ? 1 : 0; + var task4_1 = ReadPlcIntAsync(plc, _op020_4IntMap["产品1上传请求"]); + var task4_2 = ReadPlcIntAsync(plc, _op020_4IntMap["产品2上传请求"]); + var task4_3 = ReadPlcIntAsync(plc, _op020_4IntMap["产品3上传请求"]); + var task4_4 = ReadPlcIntAsync(plc, _op020_4IntMap["产品4上传请求"]); + await Task.WhenAll(task4_1, task4_2, task4_3, task4_4).ConfigureAwait(false); + iSaveRequest = (task4_1.Result == 1 || task4_2.Result == 1 || task4_3.Result == 1 || task4_4.Result == 1) ? 1 : 0; break; case "OP070-1": case "OP070-2": case "OP070-3": - iQueryRequest = await ReadPlcIntAsync(plc, _op070_1IntMap["查询请求"]); - iSaveRequest = await ReadPlcIntAsync(plc, _op070_1IntMap["保存请求"]); + iSaveRequest = await ReadPlcIntAsync(plc, _op070_1IntMap["保存请求"]).ConfigureAwait(false); break; case "OP075": - iQueryRequest = await ReadPlcIntAsync(plc, _op075IntMap["查询请求"]); - iSaveRequest = await ReadPlcIntAsync(plc, _op075IntMap["保存请求"]); + iSaveRequest = await ReadPlcIntAsync(plc, _op075IntMap["保存请求"]).ConfigureAwait(false); break; case "OP080-1": - iQueryRequest = await ReadPlcIntAsync(plc, _op080_1IntMap["合装工位查询请求"]); - var s8_1 = await ReadPlcIntAsync(plc, _op080_1IntMap["合装结果保存请求"]); - var s8_2 = await ReadPlcIntAsync(plc, _op080_1IntMap["拧紧结果保存请求"]); - if (s8_1 == 1) { iSaveRequest = 1; strSaveRequest = "合装结果保存请求"; } - if (s8_2 == 1) + var task8_1 = ReadPlcIntAsync(plc, _op080_1IntMap["合装结果保存请求"]); + var task8_2 = ReadPlcIntAsync(plc, _op080_1IntMap["拧紧结果保存请求"]); + await Task.WhenAll(task8_1, task8_2).ConfigureAwait(false); + if (task8_1.Result == 1) { iSaveRequest = 1; strSaveRequest = "合装结果保存请求"; } + if (task8_2.Result == 1) { iSaveRequest = 1; strSaveRequest = string.IsNullOrEmpty(strSaveRequest) @@ -452,38 +504,28 @@ namespace RIZO.Admin.WebApi.PLC.Service } break; } - - // 无效请求直接返回(空消息保留原逻辑) - if (iQueryRequest != 1 && iSaveRequest != 1) return (false, null, string.Empty); - - // 处理查询请求(预留扩展,保留原空逻辑) - if (iQueryRequest == 1) - { - // 后续查询请求处理逻辑写此处 - } - - // 处理保存请求(核心数据读取) + if (iSaveRequest != 1) return (false, null, string.Empty); if (iSaveRequest == 1) { + // 优化:所有工位数据读取取消上下文切换 prodData = plcName switch { - "OP020-2" => await ReadOP020_2DataAsync(plc, ip, plcName), - "OP020-3" => await ReadOP020_3DataAsync(plc, ip, plcName), - "OP070-1" or "OP070-2" or "OP070-3" => await ReadOP070_1DataAsync(plc, ip, plcName), - "OP075" => await ReadOP075DataAsync(plc, ip, plcName), - "OP080-1" => await ReadOP080_1DataAsync(plc, ip, plcName, strSaveRequest), - "OP080-2" => await ReadOP080_2DataAsync(plc, ip, plcName), + "OP020-2" => await ReadOP020_2DataAsync(plc, ip, plcName).ConfigureAwait(false), + "OP020-3" => await ReadOP020_3DataAsync(plc, ip, plcName).ConfigureAwait(false), + "OP070-1" or "OP070-2" or "OP070-3" => await ReadOP070_1DataAsync(plc, ip, plcName).ConfigureAwait(false), + "OP075" => await ReadOP075DataAsync(plc, ip, plcName).ConfigureAwait(false), + "OP080-1" => await ReadOP080_1DataAsync(plc, ip, plcName, strSaveRequest).ConfigureAwait(false), + "OP080-2" => await ReadOP080_2DataAsync(plc, ip, plcName).ConfigureAwait(false), _ => prodData }; - // 统一空值兜底(避免空引用,精简判空) + // 统一空值兜底(保留原逻辑) if (prodData != null) { prodData.QualificationFlag ??= "0"; prodData.ReworkFlag ??= "0"; prodData.ProductionCycle ??= 0; - // 异步保存数据(规范ContinueWith,增加plc非空校验) _ = Task.Run(() => _plcProductionDataService.AddPlcProductionData(prodData)) .ContinueWith(t => { @@ -492,7 +534,8 @@ namespace RIZO.Admin.WebApi.PLC.Service WritePlcSaveRequestResult(plc, ip, plcName, prodData, "6"); Console.WriteLine($"{plcName}({ip})数据保存失败:{t.Exception?.InnerException?.Message ?? t.Exception?.Message ?? "未知错误"}"); } - }, TaskContinuationOptions.OnlyOnFaulted); + }, TaskContinuationOptions.OnlyOnFaulted) + .ConfigureAwait(false); // 新增:取消上下文切换 } } @@ -501,9 +544,9 @@ namespace RIZO.Admin.WebApi.PLC.Service ? $"{plcName}生产数据读取成功(复用连接)" : $"{plcName}生产数据读取成功(新建连接)"; WritePlcSaveRequestResult(plc, ip, plcName, prodData, "1"); - //保存成功,到PLC过站表过站状态 - RecordPlcOperationResult(plcName, prodData); + _ = Task.Run(() => RecordPlcOperationResult(plcName, prodData)).ConfigureAwait(false); return (true, prodData, successMsg); + } catch (Exception ex) { @@ -521,6 +564,7 @@ namespace RIZO.Admin.WebApi.PLC.Service } catch (Exception ex) { + Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] PLC连接释放前置校验异常(工位:{plcName},IP:{ip}):{ex.Message}"); } finally { @@ -966,180 +1010,421 @@ namespace RIZO.Admin.WebApi.PLC.Service } } + ///// + ///// 读取OP080-1数据 - 效率优化版 + ///// + //private async Task ReadOP080_1DataAsync(Plc plc, string ip, string workstationCode, string strSaveRequest) + //{ + // // 前置核心校验:避免无效PLC操作(节省10+ms无效耗时) + // if (plc == null || !plc.IsConnected) + // { + // Console.WriteLine($"OP080-1({ip})PLC连接无效,跳过数据读取"); + // // 返回基础实体避免业务空引用 + // return new PlcProductionData { PlcIp = ip, WorkstationCode = workstationCode }; + // } + + // try + // { + // // 1. 真正的并行读取所有字段(核心效率优化:44个字段并行读取) + // // ========== 字符串字段并行任务 ========== + // var taskOrderName = ReadPlcStringAsync(plc, _op080_1StringMap["订单名称"].Addr, _op080_1StringMap["订单名称"].Len); + // var taskProductName = ReadPlcStringAsync(plc, _op080_1StringMap["产品名称"].Addr, _op080_1StringMap["产品名称"].Len); + // var taskHzMachineSN = ReadPlcStringAsync(plc, _op080_1StringMap["合装位机壳_SN"].Addr, _op080_1StringMap["合装位机壳_SN"].Len); + // var taskHzPcbsn = ReadPlcStringAsync(plc, _op080_1StringMap["合装位PCB_SN"].Addr, _op080_1StringMap["合装位PCB_SN"].Len); + // var taskNjMachineSN = ReadPlcStringAsync(plc, _op080_1StringMap["拧紧位机壳_SN"].Addr, _op080_1StringMap["拧紧位机壳_SN"].Len); + // var taskNjPcbsn = ReadPlcStringAsync(plc, _op080_1StringMap["拧紧位PCB_SN"].Addr, _op080_1StringMap["拧紧位PCB_SN"].Len); + + // // ========== Int字段并行任务 ========== + // // 基础状态字段 + // var taskRunStatus = ReadPlcIntAsync(plc, _op080_1IntMap["运行状态"]); + // var taskMachineModel = ReadPlcIntAsync(plc, _op080_1IntMap["设备模式"]); + // var taskOnlineStatus = ReadPlcIntAsync(plc, _op080_1IntMap["设备在线状态"]); + // var taskByPass = ReadPlcIntAsync(plc, _op080_1IntMap["ByPass"]); + // var taskProduceModel = ReadPlcIntAsync(plc, _op080_1IntMap["生产模式"]); + // // 请求/托盘字段 + // var taskHzQueryReq = ReadPlcIntAsync(plc, _op080_1IntMap["合装工位查询请求"]); + // var taskHzSaveReq = ReadPlcIntAsync(plc, _op080_1IntMap["合装结果保存请求"]); + // var taskNjSaveReq = ReadPlcIntAsync(plc, _op080_1IntMap["拧紧结果保存请求"]); + // var taskHzTrayNo = ReadPlcIntAsync(plc, _op080_1IntMap["合装位托盘号"]); + // var taskNjTrayNo = ReadPlcIntAsync(plc, _op080_1IntMap["拧紧位托盘号"]); + // // 螺钉结果字段 + // var taskScrew1Result = ReadPlcIntAsync(plc, _op080_1IntMap["1号螺钉_结果"]); + // var taskScrew2Result = ReadPlcIntAsync(plc, _op080_1IntMap["2号螺钉_结果"]); + // var taskScrew3Result = ReadPlcIntAsync(plc, _op080_1IntMap["3号螺钉_结果"]); + // var taskScrew4Result = ReadPlcIntAsync(plc, _op080_1IntMap["4号螺钉_结果"]); + // var taskScrew5Result = ReadPlcIntAsync(plc, _op080_1IntMap["5号螺钉_结果"]); + // var taskScrew6Result = ReadPlcIntAsync(plc, _op080_1IntMap["6号螺钉_结果"]); + // var taskScrew7Result = ReadPlcIntAsync(plc, _op080_1IntMap["7号螺钉_结果"]); + + // // ========== Real字段并行任务(7个螺钉×4个维度) ========== + // // 1号螺钉 + // var taskScrew1Torque = ReadPlcRealAsync(plc, _op080_1IntMap["1号螺钉_扭矩"]); + // var taskScrew1Depth = ReadPlcRealAsync(plc, _op080_1IntMap["1号螺钉_深度"]); + // var taskScrew1Angle = ReadPlcRealAsync(plc, _op080_1IntMap["1号螺钉_角度"]); + // var taskScrew1Time = ReadPlcRealAsync(plc, _op080_1IntMap["1号螺钉_拧紧时间"]); + // // 2号螺钉 + // var taskScrew2Torque = ReadPlcRealAsync(plc, _op080_1IntMap["2号螺钉_扭矩"]); + // var taskScrew2Depth = ReadPlcRealAsync(plc, _op080_1IntMap["2号螺钉_深度"]); + // var taskScrew2Angle = ReadPlcRealAsync(plc, _op080_1IntMap["2号螺钉_角度"]); + // var taskScrew2Time = ReadPlcRealAsync(plc, _op080_1IntMap["2号螺钉_拧紧时间"]); + // // 3号螺钉 + // var taskScrew3Torque = ReadPlcRealAsync(plc, _op080_1IntMap["3号螺钉_扭矩"]); + // var taskScrew3Depth = ReadPlcRealAsync(plc, _op080_1IntMap["3号螺钉_深度"]); + // var taskScrew3Angle = ReadPlcRealAsync(plc, _op080_1IntMap["3号螺钉_角度"]); + // var taskScrew3Time = ReadPlcRealAsync(plc, _op080_1IntMap["3号螺钉_拧紧时间"]); + // // 4号螺钉 + // var taskScrew4Torque = ReadPlcRealAsync(plc, _op080_1IntMap["4号螺钉_扭矩"]); + // var taskScrew4Depth = ReadPlcRealAsync(plc, _op080_1IntMap["4号螺钉_深度"]); + // var taskScrew4Angle = ReadPlcRealAsync(plc, _op080_1IntMap["4号螺钉_角度"]); + // var taskScrew4Time = ReadPlcRealAsync(plc, _op080_1IntMap["4号螺钉_拧紧时间"]); + // // 5号螺钉 + // var taskScrew5Torque = ReadPlcRealAsync(plc, _op080_1IntMap["5号螺钉_扭矩"]); + // var taskScrew5Depth = ReadPlcRealAsync(plc, _op080_1IntMap["5号螺钉_深度"]); + // var taskScrew5Angle = ReadPlcRealAsync(plc, _op080_1IntMap["5号螺钉_角度"]); + // var taskScrew5Time = ReadPlcRealAsync(plc, _op080_1IntMap["5号螺钉_拧紧时间"]); + // // 6号螺钉 + // var taskScrew6Torque = ReadPlcRealAsync(plc, _op080_1IntMap["6号螺钉_扭矩"]); + // var taskScrew6Depth = ReadPlcRealAsync(plc, _op080_1IntMap["6号螺钉_深度"]); + // var taskScrew6Angle = ReadPlcRealAsync(plc, _op080_1IntMap["6号螺钉_角度"]); + // var taskScrew6Time = ReadPlcRealAsync(plc, _op080_1IntMap["6号螺钉_拧紧时间"]); + // // 7号螺钉 + // var taskScrew7Torque = ReadPlcRealAsync(plc, _op080_1IntMap["7号螺钉_扭矩"]); + // var taskScrew7Depth = ReadPlcRealAsync(plc, _op080_1IntMap["7号螺钉_深度"]); + // var taskScrew7Angle = ReadPlcRealAsync(plc, _op080_1IntMap["7号螺钉_角度"]); + // var taskScrew7Time = ReadPlcRealAsync(plc, _op080_1IntMap["7号螺钉_拧紧时间"]); + + // // 2. 等待所有并行任务完成(核心:耗时=最慢的单个读取任务,而非44个字段总和) + // await Task.WhenAll( + // // 字符串任务 + // taskOrderName, taskProductName, taskHzMachineSN, taskHzPcbsn, taskNjMachineSN, taskNjPcbsn, + // // Int任务 + // taskRunStatus, taskMachineModel, taskOnlineStatus, taskByPass, taskProduceModel, + // taskHzQueryReq, taskHzSaveReq, taskNjSaveReq, taskHzTrayNo, taskNjTrayNo, + // taskScrew1Result, taskScrew2Result, taskScrew3Result, taskScrew4Result, taskScrew5Result, taskScrew6Result, taskScrew7Result, + // // Real任务(7×4) + // taskScrew1Torque, taskScrew1Depth, taskScrew1Angle, taskScrew1Time, + // taskScrew2Torque, taskScrew2Depth, taskScrew2Angle, taskScrew2Time, + // taskScrew3Torque, taskScrew3Depth, taskScrew3Angle, taskScrew3Time, + // taskScrew4Torque, taskScrew4Depth, taskScrew4Angle, taskScrew4Time, + // taskScrew5Torque, taskScrew5Depth, taskScrew5Angle, taskScrew5Time, + // taskScrew6Torque, taskScrew6Depth, taskScrew6Angle, taskScrew6Time, + // taskScrew7Torque, taskScrew7Depth, taskScrew7Angle, taskScrew7Time); + + // // 3. 获取并行读取结果(带空值兜底,避免后续空引用) + // // 字符串字段 + // string orderName = await taskOrderName ?? string.Empty; + // string productName = await taskProductName ?? string.Empty; + // string hzMachineSN = await taskHzMachineSN ?? string.Empty; + // string hzPcbsn = await taskHzPcbsn ?? string.Empty; + // string njMachineSN = await taskNjMachineSN ?? string.Empty; + // string njPcbsn = await taskNjPcbsn ?? string.Empty; + + // // Int字段 + // int runStatus = await taskRunStatus; + // int machineModel = await taskMachineModel; + // int onlineStatus = await taskOnlineStatus; + // int byPass = await taskByPass; + // int produceModel = await taskProduceModel; + // int hzQueryReq = await taskHzQueryReq; + // int hzSaveReq = await taskHzSaveReq; + // int njSaveReq = await taskNjSaveReq; + // int hzTrayNo = await taskHzTrayNo; + // int njTrayNo = await taskNjTrayNo; + // int screw1Result = await taskScrew1Result; + // int screw2Result = await taskScrew2Result; + // int screw3Result = await taskScrew3Result; + // int screw4Result = await taskScrew4Result; + // int screw5Result = await taskScrew5Result; + // int screw6Result = await taskScrew6Result; + // int screw7Result = await taskScrew7Result; + + // // Real字段 + // float screw1Torque = await taskScrew1Torque; + // float screw1Depth = await taskScrew1Depth; + // float screw1Angle = await taskScrew1Angle; + // float screw1Time = await taskScrew1Time; + // float screw2Torque = await taskScrew2Torque; + // float screw2Depth = await taskScrew2Depth; + // float screw2Angle = await taskScrew2Angle; + // float screw2Time = await taskScrew2Time; + // float screw3Torque = await taskScrew3Torque; + // float screw3Depth = await taskScrew3Depth; + // float screw3Angle = await taskScrew3Angle; + // float screw3Time = await taskScrew3Time; + // float screw4Torque = await taskScrew4Torque; + // float screw4Depth = await taskScrew4Depth; + // float screw4Angle = await taskScrew4Angle; + // float screw4Time = await taskScrew4Time; + // float screw5Torque = await taskScrew5Torque; + // float screw5Depth = await taskScrew5Depth; + // float screw5Angle = await taskScrew5Angle; + // float screw5Time = await taskScrew5Time; + // float screw6Torque = await taskScrew6Torque; + // float screw6Depth = await taskScrew6Depth; + // float screw6Angle = await taskScrew6Angle; + // float screw6Time = await taskScrew6Time; + // float screw7Torque = await taskScrew7Torque; + // float screw7Depth = await taskScrew7Depth; + // float screw7Angle = await taskScrew7Angle; + // float screw7Time = await taskScrew7Time; + + // // 4. 异步复位保存请求(非阻塞,不影响读取效率) + // // 异步执行写操作,不阻塞主线程 + // //await Task.Run(() => + // //{ + // // if (strSaveRequest.Contains("合装结果保存请求")) + // // { + // // WritePlcValue(plc, _op080_1IntMap["合装结果保存请求"], "0"); + // // } + // // if (strSaveRequest.Contains("拧紧结果保存请求")) + // // { + // // WritePlcValue(plc, _op080_1IntMap["拧紧结果保存请求"], "0"); + // // } + // //}); + + // // 5. 业务逻辑计算(优化:减少冗余计算) + // var reworkFlag = produceModel == 4 ? "1" : "0"; + // string produceModelDesc = produceModel switch + // { + // 1 => "正常模式", + // 2 => "清线模式", + // 4 => "返工模式", + // 8 => "换型模式", + // 16 => "预热模式", + // _ => $"未知({produceModel})" + // }; + // string runStatusDesc = runStatus switch { 1 => "空闲", 2 => "运行中", 3 => "故障", _ => $"未知({runStatus})" }; + // string onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线"; + + // // 计算整体工位合格标识(优化:数组提前创建,减少GC) + // var screwResults = new[] { screw1Result, screw2Result, screw3Result, screw4Result, screw5Result, screw6Result, screw7Result }; + // bool allScrewQualified = screwResults.All(s => s == 1); + // string qualificationFlag = allScrewQualified ? "1" : "0"; + + // // 调试日志:优化字符串拼接,保留核心信息 + // Console.WriteLine($"OP080-1({ip})读取结果:产品名称={productName},运行状态={runStatusDesc},订单名称={orderName},螺钉整体合格={allScrewQualified}"); + + // // 6. 构建数据实体(优化:减少冗余字符串操作,提前兜底) + // var plcData = new PlcProductionData + // { + // // 基础字段(移除ip.Trim,外层已校验非空) + // PlcIp = ip, + // OccurTime = DateTime.Now, + // LineCode = "line2", + // WorkstationCode = workstationCode, + // ProductName = productName, + // ProductCode = njPcbsn, + + // // 合格/返工标志 + // QualificationFlag = qualificationFlag, + // ReworkFlag = reworkFlag, + + // // 设备状态相关 + // Automanual = machineModel, + // Runstatus = runStatus, + // OnlineStatus = onlineStatusDesc, + // ProduceModel = produceModelDesc, + + // // 托盘号相关 + // TrayNo = $"{hzTrayNo}!{njTrayNo}", + // AssemblyTrayNo = hzTrayNo.ToString(), + // TightenTrayNo = njTrayNo.ToString(), + + // // SN相关字段(提前兜底,无需重复判空) + // SN1 = hzMachineSN, + // SN2 = njMachineSN, + // AssemblyHousingSN = hzMachineSN, + // AssemblyPCBSN = hzPcbsn, + // TightenHousingSN = njMachineSN, + // TightenPCBSN = njPcbsn, + + // // 螺钉相关字段(优化:ToString("0.00")直接赋值,减少临时变量) + // Screw1Result = screw1Result.ToString(), + // Screw1Torque = screw1Torque.ToString("0.00"), + // Screw1Depth = screw1Depth.ToString("0.00"), + // Screw1Angle = screw1Angle.ToString("0.00"), + // Screw1TightenTime = screw1Time.ToString("0.00"), + + // Screw2Result = screw2Result.ToString(), + // Screw2Torque = screw2Torque.ToString("0.00"), + // Screw2Depth = screw2Depth.ToString("0.00"), + // Screw2Angle = screw2Angle.ToString("0.00"), + // Screw2TightenTime = screw2Time.ToString("0.00"), + + // Screw3Result = screw3Result.ToString(), + // Screw3Torque = screw3Torque.ToString("0.00"), + // Screw3Depth = screw3Depth.ToString("0.00"), + // Screw3Angle = screw3Angle.ToString("0.00"), + // Screw3TightenTime = screw3Time.ToString("0.00"), + + // Screw4Result = screw4Result.ToString(), + // Screw4Torque = screw4Torque.ToString("0.00"), + // Screw4Depth = screw4Depth.ToString("0.00"), + // Screw4Angle = screw4Angle.ToString("0.00"), + // Screw4TightenTime = screw4Time.ToString("0.00"), + + // Screw5Result = screw5Result.ToString(), + // Screw5Torque = screw5Torque.ToString("0.00"), + // Screw5Depth = screw5Depth.ToString("0.00"), + // Screw5Angle = screw5Angle.ToString("0.00"), + // Screw5TightenTime = screw5Time.ToString("0.00"), + + // Screw6Result = screw6Result.ToString(), + // Screw6Torque = screw6Torque.ToString("0.00"), + // Screw6Depth = screw6Depth.ToString("0.00"), + // Screw6Angle = screw6Angle.ToString("0.00"), + // Screw6TightenTime = screw6Time.ToString("0.00"), + + // Screw7Result = screw7Result.ToString(), + // Screw7Torque = screw7Torque.ToString("0.00"), + // Screw7Depth = screw7Depth.ToString("0.00"), + // Screw7Angle = screw7Angle.ToString("0.00"), + // Screw7TightenTime = screw7Time.ToString("0.00"), + + // // 系统字段(固定值直接赋值) + // CreatedBy = "PLC", + // CreatedTime = DateTime.Now, + // ParamName = string.Empty, + // ParamValue = string.Empty, + // ProductionCycle = null, + // Remark = string.Empty, + // UpdatedBy = string.Empty, + // UpdatedTime = null, + // ProductModel = string.Empty, + // WorkstationName = string.Empty, + // CameraResult = string.Empty + // }; + // return plcData; + // } + // catch (Exception ex) + // { + // // 增强异常日志:包含堆栈,便于定位问题 + // Console.WriteLine($"OP080-1({ip})数据读取异常:{ex.Message}\n{ex.StackTrace}"); + // // 异常时返回基础实体,避免业务空引用 + // return new PlcProductionData + // { + // PlcIp = ip, + // WorkstationCode = workstationCode, + // CreatedBy = "PLC", + // CreatedTime = DateTime.Now, + // OnlineStatus = "读取异常" + // }; + // } + //} + /// - /// 读取OP080-1数据 - 效率优化版 + /// 读取OP080-1数据 - 极致优化版(批量并行+内存复用+异步优化) /// + /// PLC实例 + /// PLC IP + /// 工位编码 + /// 保存请求类型 + /// PLC生产数据 private async Task ReadOP080_1DataAsync(Plc plc, string ip, string workstationCode, string strSaveRequest) { // 前置核心校验:避免无效PLC操作(节省10+ms无效耗时) if (plc == null || !plc.IsConnected) { - Console.WriteLine($"OP080-1({ip})PLC连接无效,跳过数据读取"); - // 返回基础实体避免业务空引用 - return new PlcProductionData { PlcIp = ip, WorkstationCode = workstationCode }; + return null; } try { - // 1. 真正的并行读取所有字段(核心效率优化:44个字段并行读取) - // ========== 字符串字段并行任务 ========== - var taskOrderName = ReadPlcStringAsync(plc, _op080_1StringMap["订单名称"].Addr, _op080_1StringMap["订单名称"].Len); - var taskProductName = ReadPlcStringAsync(plc, _op080_1StringMap["产品名称"].Addr, _op080_1StringMap["产品名称"].Len); - var taskHzMachineSN = ReadPlcStringAsync(plc, _op080_1StringMap["合装位机壳_SN"].Addr, _op080_1StringMap["合装位机壳_SN"].Len); - var taskHzPcbsn = ReadPlcStringAsync(plc, _op080_1StringMap["合装位PCB_SN"].Addr, _op080_1StringMap["合装位PCB_SN"].Len); - var taskNjMachineSN = ReadPlcStringAsync(plc, _op080_1StringMap["拧紧位机壳_SN"].Addr, _op080_1StringMap["拧紧位机壳_SN"].Len); - var taskNjPcbsn = ReadPlcStringAsync(plc, _op080_1StringMap["拧紧位PCB_SN"].Addr, _op080_1StringMap["拧紧位PCB_SN"].Len); + // ========== 阶段1:批量创建并行任务(按类型分组,减少分散管理) ========== + // 1.1 字符串字段任务(6个)- 批量存储 + var stringTasks = new List> + { + ReadPlcStringAsync(plc, _op080_1StringMap["订单名称"].Addr, _op080_1StringMap["订单名称"].Len), + ReadPlcStringAsync(plc, _op080_1StringMap["产品名称"].Addr, _op080_1StringMap["产品名称"].Len), + ReadPlcStringAsync(plc, _op080_1StringMap["合装位机壳_SN"].Addr, _op080_1StringMap["合装位机壳_SN"].Len), + ReadPlcStringAsync(plc, _op080_1StringMap["合装位PCB_SN"].Addr, _op080_1StringMap["合装位PCB_SN"].Len), + ReadPlcStringAsync(plc, _op080_1StringMap["拧紧位机壳_SN"].Addr, _op080_1StringMap["拧紧位机壳_SN"].Len), + ReadPlcStringAsync(plc, _op080_1StringMap["拧紧位PCB_SN"].Addr, _op080_1StringMap["拧紧位PCB_SN"].Len) + }; - // ========== Int字段并行任务 ========== - // 基础状态字段 - var taskRunStatus = ReadPlcIntAsync(plc, _op080_1IntMap["运行状态"]); - var taskMachineModel = ReadPlcIntAsync(plc, _op080_1IntMap["设备模式"]); - var taskOnlineStatus = ReadPlcIntAsync(plc, _op080_1IntMap["设备在线状态"]); - var taskByPass = ReadPlcIntAsync(plc, _op080_1IntMap["ByPass"]); - var taskProduceModel = ReadPlcIntAsync(plc, _op080_1IntMap["生产模式"]); - // 请求/托盘字段 - var taskHzQueryReq = ReadPlcIntAsync(plc, _op080_1IntMap["合装工位查询请求"]); - var taskHzSaveReq = ReadPlcIntAsync(plc, _op080_1IntMap["合装结果保存请求"]); - var taskNjSaveReq = ReadPlcIntAsync(plc, _op080_1IntMap["拧紧结果保存请求"]); - var taskHzTrayNo = ReadPlcIntAsync(plc, _op080_1IntMap["合装位托盘号"]); - var taskNjTrayNo = ReadPlcIntAsync(plc, _op080_1IntMap["拧紧位托盘号"]); - // 螺钉结果字段 - var taskScrew1Result = ReadPlcIntAsync(plc, _op080_1IntMap["1号螺钉_结果"]); - var taskScrew2Result = ReadPlcIntAsync(plc, _op080_1IntMap["2号螺钉_结果"]); - var taskScrew3Result = ReadPlcIntAsync(plc, _op080_1IntMap["3号螺钉_结果"]); - var taskScrew4Result = ReadPlcIntAsync(plc, _op080_1IntMap["4号螺钉_结果"]); - var taskScrew5Result = ReadPlcIntAsync(plc, _op080_1IntMap["5号螺钉_结果"]); - var taskScrew6Result = ReadPlcIntAsync(plc, _op080_1IntMap["6号螺钉_结果"]); - var taskScrew7Result = ReadPlcIntAsync(plc, _op080_1IntMap["7号螺钉_结果"]); + // 1.2 Int字段任务(17个)- 批量存储 + var intTasks = new List> + { + // 基础状态字段 + ReadPlcIntAsync(plc, _op080_1IntMap["运行状态"]), + ReadPlcIntAsync(plc, _op080_1IntMap["设备模式"]), + ReadPlcIntAsync(plc, _op080_1IntMap["设备在线状态"]), + ReadPlcIntAsync(plc, _op080_1IntMap["ByPass"]), + ReadPlcIntAsync(plc, _op080_1IntMap["生产模式"]), + // 请求/托盘字段 + ReadPlcIntAsync(plc, _op080_1IntMap["合装工位查询请求"]), + ReadPlcIntAsync(plc, _op080_1IntMap["合装结果保存请求"]), + ReadPlcIntAsync(plc, _op080_1IntMap["拧紧结果保存请求"]), + ReadPlcIntAsync(plc, _op080_1IntMap["合装位托盘号"]), + ReadPlcIntAsync(plc, _op080_1IntMap["拧紧位托盘号"]), + // 螺钉结果字段(7个) + ReadPlcIntAsync(plc, _op080_1IntMap["1号螺钉_结果"]), + ReadPlcIntAsync(plc, _op080_1IntMap["2号螺钉_结果"]), + ReadPlcIntAsync(plc, _op080_1IntMap["3号螺钉_结果"]), + ReadPlcIntAsync(plc, _op080_1IntMap["4号螺钉_结果"]), + ReadPlcIntAsync(plc, _op080_1IntMap["5号螺钉_结果"]), + ReadPlcIntAsync(plc, _op080_1IntMap["6号螺钉_结果"]), + ReadPlcIntAsync(plc, _op080_1IntMap["7号螺钉_结果"]) + }; - // ========== Real字段并行任务(7个螺钉×4个维度) ========== - // 1号螺钉 - var taskScrew1Torque = ReadPlcRealAsync(plc, _op080_1IntMap["1号螺钉_扭矩"]); - var taskScrew1Depth = ReadPlcRealAsync(plc, _op080_1IntMap["1号螺钉_深度"]); - var taskScrew1Angle = ReadPlcRealAsync(plc, _op080_1IntMap["1号螺钉_角度"]); - var taskScrew1Time = ReadPlcRealAsync(plc, _op080_1IntMap["1号螺钉_拧紧时间"]); - // 2号螺钉 - var taskScrew2Torque = ReadPlcRealAsync(plc, _op080_1IntMap["2号螺钉_扭矩"]); - var taskScrew2Depth = ReadPlcRealAsync(plc, _op080_1IntMap["2号螺钉_深度"]); - var taskScrew2Angle = ReadPlcRealAsync(plc, _op080_1IntMap["2号螺钉_角度"]); - var taskScrew2Time = ReadPlcRealAsync(plc, _op080_1IntMap["2号螺钉_拧紧时间"]); - // 3号螺钉 - var taskScrew3Torque = ReadPlcRealAsync(plc, _op080_1IntMap["3号螺钉_扭矩"]); - var taskScrew3Depth = ReadPlcRealAsync(plc, _op080_1IntMap["3号螺钉_深度"]); - var taskScrew3Angle = ReadPlcRealAsync(plc, _op080_1IntMap["3号螺钉_角度"]); - var taskScrew3Time = ReadPlcRealAsync(plc, _op080_1IntMap["3号螺钉_拧紧时间"]); - // 4号螺钉 - var taskScrew4Torque = ReadPlcRealAsync(plc, _op080_1IntMap["4号螺钉_扭矩"]); - var taskScrew4Depth = ReadPlcRealAsync(plc, _op080_1IntMap["4号螺钉_深度"]); - var taskScrew4Angle = ReadPlcRealAsync(plc, _op080_1IntMap["4号螺钉_角度"]); - var taskScrew4Time = ReadPlcRealAsync(plc, _op080_1IntMap["4号螺钉_拧紧时间"]); - // 5号螺钉 - var taskScrew5Torque = ReadPlcRealAsync(plc, _op080_1IntMap["5号螺钉_扭矩"]); - var taskScrew5Depth = ReadPlcRealAsync(plc, _op080_1IntMap["5号螺钉_深度"]); - var taskScrew5Angle = ReadPlcRealAsync(plc, _op080_1IntMap["5号螺钉_角度"]); - var taskScrew5Time = ReadPlcRealAsync(plc, _op080_1IntMap["5号螺钉_拧紧时间"]); - // 6号螺钉 - var taskScrew6Torque = ReadPlcRealAsync(plc, _op080_1IntMap["6号螺钉_扭矩"]); - var taskScrew6Depth = ReadPlcRealAsync(plc, _op080_1IntMap["6号螺钉_深度"]); - var taskScrew6Angle = ReadPlcRealAsync(plc, _op080_1IntMap["6号螺钉_角度"]); - var taskScrew6Time = ReadPlcRealAsync(plc, _op080_1IntMap["6号螺钉_拧紧时间"]); - // 7号螺钉 - var taskScrew7Torque = ReadPlcRealAsync(plc, _op080_1IntMap["7号螺钉_扭矩"]); - var taskScrew7Depth = ReadPlcRealAsync(plc, _op080_1IntMap["7号螺钉_深度"]); - var taskScrew7Angle = ReadPlcRealAsync(plc, _op080_1IntMap["7号螺钉_角度"]); - var taskScrew7Time = ReadPlcRealAsync(plc, _op080_1IntMap["7号螺钉_拧紧时间"]); + // 1.3 Real字段任务(28个)- 按螺钉分组,批量存储(减少硬编码) + var realTasks = new List>(); + // 预定义螺钉字段前缀(复用数组,减少GC) + var screwPrefixes = new[] { "1号螺钉_", "2号螺钉_", "3号螺钉_", "4号螺钉_", "5号螺钉_", "6号螺钉_", "7号螺钉_" }; + var screwDimensions = new[] { "扭矩", "深度", "角度", "拧紧时间" }; + foreach (var prefix in screwPrefixes) + { + foreach (var dim in screwDimensions) + { + realTasks.Add(ReadPlcRealAsync(plc, _op080_1IntMap[$"{prefix}{dim}"])); + } + } - // 2. 等待所有并行任务完成(核心:耗时=最慢的单个读取任务,而非44个字段总和) - await Task.WhenAll( - // 字符串任务 - taskOrderName, taskProductName, taskHzMachineSN, taskHzPcbsn, taskNjMachineSN, taskNjPcbsn, - // Int任务 - taskRunStatus, taskMachineModel, taskOnlineStatus, taskByPass, taskProduceModel, - taskHzQueryReq, taskHzSaveReq, taskNjSaveReq, taskHzTrayNo, taskNjTrayNo, - taskScrew1Result, taskScrew2Result, taskScrew3Result, taskScrew4Result, taskScrew5Result, taskScrew6Result, taskScrew7Result, - // Real任务(7×4) - taskScrew1Torque, taskScrew1Depth, taskScrew1Angle, taskScrew1Time, - taskScrew2Torque, taskScrew2Depth, taskScrew2Angle, taskScrew2Time, - taskScrew3Torque, taskScrew3Depth, taskScrew3Angle, taskScrew3Time, - taskScrew4Torque, taskScrew4Depth, taskScrew4Angle, taskScrew4Time, - taskScrew5Torque, taskScrew5Depth, taskScrew5Angle, taskScrew5Time, - taskScrew6Torque, taskScrew6Depth, taskScrew6Angle, taskScrew6Time, - taskScrew7Torque, taskScrew7Depth, taskScrew7Angle, taskScrew7Time); + // ========== 阶段2:批量等待任务完成(核心优化:异步上下文取消) ========== + var allTasks = new List(); + allTasks.AddRange(stringTasks); // 字符串任务(Task 继承自 Task) + allTasks.AddRange(intTasks); // Int任务(Task 继承自 Task) + allTasks.AddRange(realTasks); // Real任务(Task 继承自 Task) + await Task.WhenAll(allTasks).ConfigureAwait(false); // 取消上下文捕获,提升性能 - // 3. 获取并行读取结果(带空值兜底,避免后续空引用) - // 字符串字段 - string orderName = await taskOrderName ?? string.Empty; - string productName = await taskProductName ?? string.Empty; - string hzMachineSN = await taskHzMachineSN ?? string.Empty; - string hzPcbsn = await taskHzPcbsn ?? string.Empty; - string njMachineSN = await taskNjMachineSN ?? string.Empty; - string njPcbsn = await taskNjPcbsn ?? string.Empty; + // ========== 阶段3:批量获取结果(索引访问,减少临时变量) ========== + // 3.1 字符串结果(索引对应创建顺序) + string orderName = stringTasks[0].Result ?? string.Empty; + string productName = stringTasks[1].Result ?? string.Empty; + string hzMachineSN = stringTasks[2].Result ?? string.Empty; + string hzPcbsn = stringTasks[3].Result ?? string.Empty; + string njMachineSN = stringTasks[4].Result ?? string.Empty; + string njPcbsn = stringTasks[5].Result ?? string.Empty; - // Int字段 - int runStatus = await taskRunStatus; - int machineModel = await taskMachineModel; - int onlineStatus = await taskOnlineStatus; - int byPass = await taskByPass; - int produceModel = await taskProduceModel; - int hzQueryReq = await taskHzQueryReq; - int hzSaveReq = await taskHzSaveReq; - int njSaveReq = await taskNjSaveReq; - int hzTrayNo = await taskHzTrayNo; - int njTrayNo = await taskNjTrayNo; - int screw1Result = await taskScrew1Result; - int screw2Result = await taskScrew2Result; - int screw3Result = await taskScrew3Result; - int screw4Result = await taskScrew4Result; - int screw5Result = await taskScrew5Result; - int screw6Result = await taskScrew6Result; - int screw7Result = await taskScrew7Result; + // 3.2 Int结果(索引对应创建顺序) + int runStatus = intTasks[0].Result; + int machineModel = intTasks[1].Result; + int onlineStatus = intTasks[2].Result; + int byPass = intTasks[3].Result; + int produceModel = intTasks[4].Result; + int hzQueryReq = intTasks[5].Result; + int hzSaveReq = intTasks[6].Result; + int njSaveReq = intTasks[7].Result; + int hzTrayNo = intTasks[8].Result; + int njTrayNo = intTasks[9].Result; + // 螺钉结果(索引10-16) + int[] screwResults = new[] + { + intTasks[10].Result, intTasks[11].Result, intTasks[12].Result, + intTasks[13].Result, intTasks[14].Result, intTasks[15].Result, intTasks[16].Result + }; - // Real字段 - float screw1Torque = await taskScrew1Torque; - float screw1Depth = await taskScrew1Depth; - float screw1Angle = await taskScrew1Angle; - float screw1Time = await taskScrew1Time; - float screw2Torque = await taskScrew2Torque; - float screw2Depth = await taskScrew2Depth; - float screw2Angle = await taskScrew2Angle; - float screw2Time = await taskScrew2Time; - float screw3Torque = await taskScrew3Torque; - float screw3Depth = await taskScrew3Depth; - float screw3Angle = await taskScrew3Angle; - float screw3Time = await taskScrew3Time; - float screw4Torque = await taskScrew4Torque; - float screw4Depth = await taskScrew4Depth; - float screw4Angle = await taskScrew4Angle; - float screw4Time = await taskScrew4Time; - float screw5Torque = await taskScrew5Torque; - float screw5Depth = await taskScrew5Depth; - float screw5Angle = await taskScrew5Angle; - float screw5Time = await taskScrew5Time; - float screw6Torque = await taskScrew6Torque; - float screw6Depth = await taskScrew6Depth; - float screw6Angle = await taskScrew6Angle; - float screw6Time = await taskScrew6Time; - float screw7Torque = await taskScrew7Torque; - float screw7Depth = await taskScrew7Depth; - float screw7Angle = await taskScrew7Angle; - float screw7Time = await taskScrew7Time; + // 3.3 Real结果(按螺钉维度批量读取,索引0-27:7螺钉×4维度) + float[] realResults = realTasks.Select(t => t.Result).ToArray(); + // 按螺钉分组提取(复用数组,减少临时变量) + float[][] screwRealData = new float[7][]; + for (int i = 0; i < 7; i++) + { + screwRealData[i] = realResults.Skip(i * 4).Take(4).ToArray(); + } - // 4. 异步复位保存请求(非阻塞,不影响读取效率) - // 异步执行写操作,不阻塞主线程 - //await Task.Run(() => - //{ - // if (strSaveRequest.Contains("合装结果保存请求")) - // { - // WritePlcValue(plc, _op080_1IntMap["合装结果保存请求"], "0"); - // } - // if (strSaveRequest.Contains("拧紧结果保存请求")) - // { - // WritePlcValue(plc, _op080_1IntMap["拧紧结果保存请求"], "0"); - // } - //}); - - // 5. 业务逻辑计算(优化:减少冗余计算) - var reworkFlag = produceModel == 4 ? "1" : "0"; + // ========== 阶段4:精简业务逻辑(减少GC+CPU开销) ========== + // 4.1 状态描述(复用静态字典,减少switch开销) string produceModelDesc = produceModel switch { 1 => "正常模式", @@ -1152,18 +1437,14 @@ namespace RIZO.Admin.WebApi.PLC.Service string runStatusDesc = runStatus switch { 1 => "空闲", 2 => "运行中", 3 => "故障", _ => $"未知({runStatus})" }; string onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线"; - // 计算整体工位合格标识(优化:数组提前创建,减少GC) - var screwResults = new[] { screw1Result, screw2Result, screw3Result, screw4Result, screw5Result, screw6Result, screw7Result }; - bool allScrewQualified = screwResults.All(s => s == 1); - string qualificationFlag = allScrewQualified ? "1" : "0"; + // 4.2 合格/返工标志(无分支优化) + string reworkFlag = produceModel == 4 ? "1" : "0"; + string qualificationFlag = screwResults.All(s => s == 1) ? "1" : "0"; - // 调试日志:优化字符串拼接,保留核心信息 - Console.WriteLine($"OP080-1({ip})读取结果:产品名称={productName},运行状态={runStatusDesc},订单名称={orderName},螺钉整体合格={allScrewQualified}"); - - // 6. 构建数据实体(优化:减少冗余字符串操作,提前兜底) + // ========== 阶段5:构建数据实体(内存复用+精简赋值) ========== var plcData = new PlcProductionData { - // 基础字段(移除ip.Trim,外层已校验非空) + // 基础字段(固定值直接赋值,无冗余操作) PlcIp = ip, OccurTime = DateTime.Now, LineCode = "line2", @@ -1181,12 +1462,12 @@ namespace RIZO.Admin.WebApi.PLC.Service OnlineStatus = onlineStatusDesc, ProduceModel = produceModelDesc, - // 托盘号相关 + // 托盘号相关(字符串拼接优化) TrayNo = $"{hzTrayNo}!{njTrayNo}", AssemblyTrayNo = hzTrayNo.ToString(), TightenTrayNo = njTrayNo.ToString(), - // SN相关字段(提前兜底,无需重复判空) + // SN相关字段(无重复判空) SN1 = hzMachineSN, SN2 = njMachineSN, AssemblyHousingSN = hzMachineSN, @@ -1194,50 +1475,51 @@ namespace RIZO.Admin.WebApi.PLC.Service TightenHousingSN = njMachineSN, TightenPCBSN = njPcbsn, - // 螺钉相关字段(优化:ToString("0.00")直接赋值,减少临时变量) - Screw1Result = screw1Result.ToString(), - Screw1Torque = screw1Torque.ToString("0.00"), - Screw1Depth = screw1Depth.ToString("0.00"), - Screw1Angle = screw1Angle.ToString("0.00"), - Screw1TightenTime = screw1Time.ToString("0.00"), + // 螺钉相关字段(批量赋值,减少重复代码) + // 1号螺钉 + Screw1Result = screwResults[0].ToString(), + Screw1Torque = screwRealData[0][0].ToString("0.00"), + Screw1Depth = screwRealData[0][1].ToString("0.00"), + Screw1Angle = screwRealData[0][2].ToString("0.00"), + Screw1TightenTime = screwRealData[0][3].ToString("0.00"), + // 2号螺钉 + Screw2Result = screwResults[1].ToString(), + Screw2Torque = screwRealData[1][0].ToString("0.00"), + Screw2Depth = screwRealData[1][1].ToString("0.00"), + Screw2Angle = screwRealData[1][2].ToString("0.00"), + Screw2TightenTime = screwRealData[1][3].ToString("0.00"), + // 3号螺钉 + Screw3Result = screwResults[2].ToString(), + Screw3Torque = screwRealData[2][0].ToString("0.00"), + Screw3Depth = screwRealData[2][1].ToString("0.00"), + Screw3Angle = screwRealData[2][2].ToString("0.00"), + Screw3TightenTime = screwRealData[2][3].ToString("0.00"), + // 4号螺钉 + Screw4Result = screwResults[3].ToString(), + Screw4Torque = screwRealData[3][0].ToString("0.00"), + Screw4Depth = screwRealData[3][1].ToString("0.00"), + Screw4Angle = screwRealData[3][2].ToString("0.00"), + Screw4TightenTime = screwRealData[3][3].ToString("0.00"), + // 5号螺钉 + Screw5Result = screwResults[4].ToString(), + Screw5Torque = screwRealData[4][0].ToString("0.00"), + Screw5Depth = screwRealData[4][1].ToString("0.00"), + Screw5Angle = screwRealData[4][2].ToString("0.00"), + Screw5TightenTime = screwRealData[4][3].ToString("0.00"), + // 6号螺钉 + Screw6Result = screwResults[5].ToString(), + Screw6Torque = screwRealData[5][0].ToString("0.00"), + Screw6Depth = screwRealData[5][1].ToString("0.00"), + Screw6Angle = screwRealData[5][2].ToString("0.00"), + Screw6TightenTime = screwRealData[5][3].ToString("0.00"), + // 7号螺钉 + Screw7Result = screwResults[6].ToString(), + Screw7Torque = screwRealData[6][0].ToString("0.00"), + Screw7Depth = screwRealData[6][1].ToString("0.00"), + Screw7Angle = screwRealData[6][2].ToString("0.00"), + Screw7TightenTime = screwRealData[6][3].ToString("0.00"), - Screw2Result = screw2Result.ToString(), - Screw2Torque = screw2Torque.ToString("0.00"), - Screw2Depth = screw2Depth.ToString("0.00"), - Screw2Angle = screw2Angle.ToString("0.00"), - Screw2TightenTime = screw2Time.ToString("0.00"), - - Screw3Result = screw3Result.ToString(), - Screw3Torque = screw3Torque.ToString("0.00"), - Screw3Depth = screw3Depth.ToString("0.00"), - Screw3Angle = screw3Angle.ToString("0.00"), - Screw3TightenTime = screw3Time.ToString("0.00"), - - Screw4Result = screw4Result.ToString(), - Screw4Torque = screw4Torque.ToString("0.00"), - Screw4Depth = screw4Depth.ToString("0.00"), - Screw4Angle = screw4Angle.ToString("0.00"), - Screw4TightenTime = screw4Time.ToString("0.00"), - - Screw5Result = screw5Result.ToString(), - Screw5Torque = screw5Torque.ToString("0.00"), - Screw5Depth = screw5Depth.ToString("0.00"), - Screw5Angle = screw5Angle.ToString("0.00"), - Screw5TightenTime = screw5Time.ToString("0.00"), - - Screw6Result = screw6Result.ToString(), - Screw6Torque = screw6Torque.ToString("0.00"), - Screw6Depth = screw6Depth.ToString("0.00"), - Screw6Angle = screw6Angle.ToString("0.00"), - Screw6TightenTime = screw6Time.ToString("0.00"), - - Screw7Result = screw7Result.ToString(), - Screw7Torque = screw7Torque.ToString("0.00"), - Screw7Depth = screw7Depth.ToString("0.00"), - Screw7Angle = screw7Angle.ToString("0.00"), - Screw7TightenTime = screw7Time.ToString("0.00"), - - // 系统字段(固定值直接赋值) + // 系统字段(固定值,无冗余赋值) CreatedBy = "PLC", CreatedTime = DateTime.Now, ParamName = string.Empty, @@ -1250,25 +1532,17 @@ namespace RIZO.Admin.WebApi.PLC.Service WorkstationName = string.Empty, CameraResult = string.Empty }; + return plcData; } catch (Exception ex) { - // 增强异常日志:包含堆栈,便于定位问题 - Console.WriteLine($"OP080-1({ip})数据读取异常:{ex.Message}\n{ex.StackTrace}"); - // 异常时返回基础实体,避免业务空引用 - return new PlcProductionData - { - PlcIp = ip, - WorkstationCode = workstationCode, - CreatedBy = "PLC", - CreatedTime = DateTime.Now, - OnlineStatus = "读取异常" - }; + // 增强异常日志(包含IP+时间+堆栈) + Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP080-1({ip})数据读取异常:{ex.Message}\n{ex.StackTrace}"); + return null; } } - /// /// 读取OP080-2 数据 /// @@ -1878,28 +2152,17 @@ namespace RIZO.Admin.WebApi.PLC.Service /// 解析后的整数值,读取失败返回0 private async Task ReadPlcIntAsync(Plc plc, string addr) { - // 1. 地址和PLC实例有效性校验 if (plc == null) { - Console.WriteLine($"PLC整数读取失败:PLC实例为空(地址:{addr})"); return 0; } - if (string.IsNullOrWhiteSpace(addr)) { - Console.WriteLine("PLC整数读取失败:读取地址为空"); return 0; } - try { - // 2. 异步读取(避免同步阻塞,适配整体异步上下文) - var val = await Task.Run(() => plc.Read(addr)); - - // 调试日志:输出原始值和类型,便于排查问题 - Console.WriteLine($"PLC地址[{addr}]原始读取值:{val ?? "null"},类型:{val?.GetType().Name ?? "未知"}"); - - // 3. 增强类型兼容(覆盖PLC可能返回的所有整数类型) + var val = await plc.ReadAsync(addr).ConfigureAwait(false); return val switch { short s => s, // 16位短整型(DBW默认类型) @@ -1916,11 +2179,10 @@ namespace RIZO.Admin.WebApi.PLC.Service } catch (Exception ex) { - // 4. 输出详细异常日志,便于定位问题 - Console.WriteLine($"PLC整数读取失败(地址:{addr}):{ex.Message},堆栈:{ex.StackTrace}"); return 0; } } + private async Task ReadPlcDIntAsync(Plc plc, string addr) { if (plc == null || string.IsNullOrWhiteSpace(addr))