From df975269306f308591c567db2e1ba762a0ac9516 Mon Sep 17 00:00:00 2001 From: zqm Date: Tue, 28 Oct 2025 17:17:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=89=B2=E5=BD=A9=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Toprie/Toprie/DeviceManager.cs | 229 +++++++++--------- Windows/CS/Framework4.0/Toprie/Toprie/V8.cs | 28 +-- 2 files changed, 133 insertions(+), 124 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 71dd50d..8a0449f 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -2219,6 +2219,11 @@ namespace JoyD.Windows.CS.Toprie // 用于保护SDK操作的线程锁 private readonly object _sdkOperationLock = new object(); + // 连续心跳失败计数,用于实现容错机制 + private int _consecutiveHeartbeatFailures = 0; + // 连续心跳失败阈值,超过此值才认为连接真正断开 + private const int HEARTBEAT_FAILURE_THRESHOLD = 3; + /// /// 设置色彩模式 /// @@ -2229,125 +2234,117 @@ namespace JoyD.Windows.CS.Toprie // 添加线程锁保护,防止多线程同时操作SDK lock (_sdkOperationLock) { - // 最大重试次数 - const int maxRetries = 3; - // 重试间隔(毫秒) - const int retryDelayMs = 100; + // 暂停心跳检测,避免设置过程中发生冲突 + bool wasHeartbeatRunning = _heartbeatTimer != null; + if (wasHeartbeatRunning) + { + _heartbeatTimer.Change(Timeout.Infinite, Timeout.Infinite); + Log("设置色彩模式前暂停心跳检测"); + } - // 先获取原始值,只读取一次,避免嵌套调用 - int originalValue = -1; try { - if (_a8Sdk != null && _connectionStatus == ConnectionStatus.Connected) - { - originalValue = _a8Sdk.Color_plate; - Log($"成功读取当前色彩模式值: {originalValue}"); - } - } - catch (Exception ex) - { - Log($"获取当前色彩模式值时出错: {ex.Message}"); - // 即使获取失败,仍尝试设置新值 - } - - // 将PaletteType枚举转换为int类型 - int paletteValue = (int)paletteType; - - // 检查新的色彩模式是否与当前值相同,如果相同则不需要设置 - if (originalValue == paletteValue) - { - Log($"当前色彩模式已为目标值,无需设置"); - return true; - } - - for (int attempt = 0; attempt < maxRetries; attempt++) - { + // 最大重试次数 + const int maxRetries = 3; + // 重试间隔(毫秒) + const int retryDelayMs = 100; + + // 先获取原始值,只读取一次,避免嵌套调用 + int originalValue = -1; try { - // 检查对象状态和连接状态 - if (_a8Sdk == null || _connectionStatus != ConnectionStatus.Connected) + if (_a8Sdk != null && _connectionStatus == ConnectionStatus.Connected) { - Log($"色彩模式设置失败: {(attempt > 0 ? "重试中" : "")}SDK实例为空或设备未连接"); - Thread.Sleep(retryDelayMs); - continue; + originalValue = _a8Sdk.Color_plate; + Log($"成功读取当前色彩模式值: {originalValue}"); } - - // 已在循环外部计算paletteValue,避免重复计算 - - // 直接设置色彩模式,不再在每次尝试中读取原始值 - _a8Sdk.Color_plate = paletteValue; - - // 短暂延迟,确保设置生效 - Thread.Sleep(50); - - // 减少读取验证,避免嵌套UDP命令 - // 信任SDK的设置操作,不再额外验证 - Log($"色彩模式设置成功: {paletteType} (值: {paletteValue})"); - - // 移除图像接收重启逻辑,因为色彩模式不影响图像接收 - // 仅保留短暂延迟确保设置生效 - Thread.Sleep(200); // 给设备处理时间 - - return true; - - // 注释掉需要再次读取验证的代码,避免嵌套UDP命令 - // int currentValue = _a8Sdk.Color_plate; - // if (currentValue == paletteValue) - // {","},{ - // } - // else - // { - // // 设置失败,记录日志并准备重试 - // Log($"色彩模式设置失败: 尝试 {attempt + 1}/{maxRetries},未能确认设置生效,当前值: {currentValue}"); - // - // // 如果已经是最后一次尝试,则恢复原始值 - // // if (attempt == maxRetries - 1) - // // {","},{ - // try - // { - // _a8Sdk.Color_plate = originalValue; - // Log($"已恢复原始色彩模式值: {originalValue}"); - // } - // catch (Exception restoreEx) - // { - // Log($"恢复原始色彩模式失败: {restoreEx.Message}"); - // } - // } - - // 重试前等待 - // Thread.Sleep(retryDelayMs); - // } } catch (Exception ex) { - Log($"设置色彩模式异常 (尝试 {attempt + 1}/{maxRetries}): {ex.Message}"); - - // 简化SDK状态检查,避免触发额外的UDP命令 - Log($"SDK状态监控: 色彩模式设置操作失败"); - - // 重试前等待 - Thread.Sleep(retryDelayMs); + Log($"获取当前色彩模式值时出错: {ex.Message}"); + // 即使获取失败,仍尝试设置新值 } + + // 将PaletteType枚举转换为int类型 + int paletteValue = (int)paletteType; + + // 检查新的色彩模式是否与当前值相同,如果相同则不需要设置 + if (originalValue == paletteValue) + { + Log($"当前色彩模式已为目标值,无需设置"); + return true; + } + + for (int attempt = 0; attempt < maxRetries; attempt++) + { + try + { + // 检查对象状态和连接状态 + if (_a8Sdk == null || _connectionStatus != ConnectionStatus.Connected) + { + Log($"色彩模式设置失败: {(attempt > 0 ? "重试中" : "")}SDK实例为空或设备未连接"); + Thread.Sleep(retryDelayMs); + continue; + } + + // 已在循环外部计算paletteValue,避免重复计算 + + // 直接设置色彩模式,不再在每次尝试中读取原始值 + _a8Sdk.Color_plate = paletteValue; + + // 短暂延迟,确保设置生效 + Thread.Sleep(50); + + // 减少读取验证,避免嵌套UDP命令 + // 信任SDK的设置操作,不再额外验证 + Log($"色彩模式设置成功: {paletteType} (值: {paletteValue})"); + + // 移除图像接收重启逻辑,因为色彩模式不影响图像接收 + // 仅保留短暂延迟确保设置生效 + Thread.Sleep(200); // 给设备处理时间 + + return true; + } + catch (Exception ex) + { + Log($"设置色彩模式异常 (尝试 {attempt + 1}/{maxRetries}): {ex.Message}"); + + // 简化SDK状态检查,避免触发额外的UDP命令 + Log($"SDK状态监控: 色彩模式设置操作失败"); + + // 重试前等待 + Thread.Sleep(retryDelayMs); + } + } + + // 所有尝试都失败 + Log($"色彩模式设置最终失败: 已尝试{maxRetries}次"); + + // 最后一次尝试失败后,仅在有原始值的情况下尝试恢复 + if (originalValue >= 0 && _a8Sdk != null && _connectionStatus == ConnectionStatus.Connected) + { + try + { + _a8Sdk.Color_plate = originalValue; + Log($"已恢复原始色彩模式值: {originalValue}"); + } + catch (Exception restoreEx) + { + Log($"恢复原始色彩模式失败: {restoreEx.Message}"); + } + } + + return false; } - - // 所有尝试都失败 - Log($"色彩模式设置最终失败: 已尝试{maxRetries}次"); - - // 最后一次尝试失败后,仅在有原始值的情况下尝试恢复 - if (originalValue >= 0 && _a8Sdk != null && _connectionStatus == ConnectionStatus.Connected) + finally { - try + // 无论设置成功与否,都恢复心跳检测 + if (wasHeartbeatRunning && _heartbeatTimer != null) { - _a8Sdk.Color_plate = originalValue; - Log($"已恢复原始色彩模式值: {originalValue}"); - } - catch (Exception restoreEx) - { - Log($"恢复原始色彩模式失败: {restoreEx.Message}"); + _heartbeatTimer.Change(_heartbeatInterval, _heartbeatInterval); + Log("设置色彩模式后恢复心跳检测"); } } - - return false; } } @@ -3817,7 +3814,9 @@ namespace JoyD.Windows.CS.Toprie if (heartbeatResult > 0) { heartbeatSuccessful = true; - Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] HeartbeatCallback() - 心跳检测成功 (第{i+1}次尝试)"); + // 心跳成功,重置连续失败计数 + _consecutiveHeartbeatFailures = 0; + Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] HeartbeatCallback() - 心跳检测成功 (第{i+1}次尝试),连续失败计数已重置"); // 定期更新连接状态,表明连接正常 if (_connectionStatus != ConnectionStatus.Connected) { @@ -3850,13 +3849,25 @@ namespace JoyD.Windows.CS.Toprie if (!heartbeatSuccessful) { - Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] HeartbeatCallback() - SDK心跳检测失败,连接可能已断开"); - UpdateConnectionStatus(ConnectionStatus.Disconnected, "SDK心跳检测失败,连接已断开"); + // 心跳失败,增加连续失败计数 + _consecutiveHeartbeatFailures++; + Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] HeartbeatCallback() - SDK心跳检测失败,连续失败计数: {_consecutiveHeartbeatFailures}/{HEARTBEAT_FAILURE_THRESHOLD}"); - // 如果启用了自动重连,开始重连 - if (_isAutoReconnectEnabled) + // 只有当连续失败次数超过阈值时,才断开连接 + if (_consecutiveHeartbeatFailures >= HEARTBEAT_FAILURE_THRESHOLD) { - StartAutoReconnect(); + Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] HeartbeatCallback() - 连续心跳失败次数超过阈值,确认连接已断开"); + UpdateConnectionStatus(ConnectionStatus.Disconnected, "SDK心跳检测连续失败,连接已断开"); + + // 如果启用了自动重连,开始重连 + if (_isAutoReconnectEnabled) + { + StartAutoReconnect(); + } + } + else + { + Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] HeartbeatCallback() - 连续心跳失败次数未达阈值,暂时保留连接状态"); } } } diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs index 8e8e82b..f30c411 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs @@ -31,7 +31,8 @@ namespace JoyD.Windows.CS.Toprie { SHUTTER_CORRECTION = 0, SET_AUTO_SHUTTER = 1, - SET_COLOR_PLATE = 2, + // 根据热像仪SDK,设置色彩模式的命令类型 + SET_COLOR_PLATE = 2, // 保持为2,因为热像仪SDK中也是使用SET_COLOR_PLATE命令 SET_MIRROR_VIDEO = 3, SET_VIDEO_MODE = 4, SET_AREA_POS = 5, @@ -46,10 +47,10 @@ namespace JoyD.Windows.CS.Toprie SET_EMAIL_SERVER = 14, SET_TFTP_SERVER = 15, SET_NETWORK_ETH = 16, - SET_FUSION_DISTANCE = 17, - SET_ENVIR_PARAM = 18, - SET_ALARM_PARAM = 19, - GET_PARAMETER = 20, + GET_PARAMETER = 17, + SET_FUSION_DISTANCE = 18, + SET_ENVIR_PARAM = 19, + SET_ALARM_PARAM = 20, POWER_REBOOT = 21, PARAM_RECOVER = 22, UPDATER = 23, @@ -273,13 +274,10 @@ namespace JoyD.Windows.CS.Toprie try { - // 从第5个字符开始解析数值 (+RET:值$) - int endIndex = response.IndexOf('$'); - if (endIndex > 5) - { - string valueStr = response.Substring(5, endIndex - 5); - return int.Parse(valueStr); - } + // 从第5个字符开始解析数值,与热像仪SDK保持一致 + // SDK使用atoi(buff + 5)直接解析,不检查$符号 + string valueStr = response.Substring(5); + return int.Parse(valueStr); } catch (Exception ex) { @@ -637,9 +635,9 @@ namespace JoyD.Windows.CS.Toprie { Log($"[色彩模式设置] 验证成功,当前值确认为: {validatedValue}"); - // 设置成功后重启图像接收以避免卡顿 - Log($"[色彩模式设置] 设置成功后重启图像接收以避免卡顿"); - SafeRestartImageReceiving(); + // 移除图像接收重启逻辑,因为色彩模式不影响图像接收 + // 仅保留短暂延迟确保设置生效 + Log($"[色彩模式设置] 设置成功,不需要重启图像接收"); } else {