修改色彩模式获取逻辑

This commit is contained in:
zqm
2025-10-28 17:17:05 +08:00
parent bfbe7696f3
commit df97526930
2 changed files with 133 additions and 124 deletions

View File

@@ -2219,6 +2219,11 @@ namespace JoyD.Windows.CS.Toprie
// 用于保护SDK操作的线程锁 // 用于保护SDK操作的线程锁
private readonly object _sdkOperationLock = new object(); private readonly object _sdkOperationLock = new object();
// 连续心跳失败计数,用于实现容错机制
private int _consecutiveHeartbeatFailures = 0;
// 连续心跳失败阈值,超过此值才认为连接真正断开
private const int HEARTBEAT_FAILURE_THRESHOLD = 3;
/// <summary> /// <summary>
/// 设置色彩模式 /// 设置色彩模式
/// </summary> /// </summary>
@@ -2229,125 +2234,117 @@ namespace JoyD.Windows.CS.Toprie
// 添加线程锁保护防止多线程同时操作SDK // 添加线程锁保护防止多线程同时操作SDK
lock (_sdkOperationLock) lock (_sdkOperationLock)
{ {
// 最大重试次数 // 暂停心跳检测,避免设置过程中发生冲突
const int maxRetries = 3; bool wasHeartbeatRunning = _heartbeatTimer != null;
// 重试间隔(毫秒) if (wasHeartbeatRunning)
const int retryDelayMs = 100; {
_heartbeatTimer.Change(Timeout.Infinite, Timeout.Infinite);
Log("设置色彩模式前暂停心跳检测");
}
// 先获取原始值,只读取一次,避免嵌套调用
int originalValue = -1;
try try
{ {
if (_a8Sdk != null && _connectionStatus == ConnectionStatus.Connected) // 最大重试次数
{ const int maxRetries = 3;
originalValue = _a8Sdk.Color_plate; // 重试间隔(毫秒)
Log($"成功读取当前色彩模式值: {originalValue}"); const int retryDelayMs = 100;
}
} // 先获取原始值,只读取一次,避免嵌套调用
catch (Exception ex) int originalValue = -1;
{
Log($"获取当前色彩模式值时出错: {ex.Message}");
// 即使获取失败,仍尝试设置新值
}
// 将PaletteType枚举转换为int类型
int paletteValue = (int)paletteType;
// 检查新的色彩模式是否与当前值相同,如果相同则不需要设置
if (originalValue == paletteValue)
{
Log($"当前色彩模式已为目标值,无需设置");
return true;
}
for (int attempt = 0; attempt < maxRetries; attempt++)
{
try try
{ {
// 检查对象状态和连接状态 if (_a8Sdk != null && _connectionStatus == ConnectionStatus.Connected)
if (_a8Sdk == null || _connectionStatus != ConnectionStatus.Connected)
{ {
Log($"色彩模式设置失败: {(attempt > 0 ? "" : "")}SDK实例为空或设备未连接"); originalValue = _a8Sdk.Color_plate;
Thread.Sleep(retryDelayMs); Log($"成功读取当前色彩模式值: {originalValue}");
continue;
} }
// 已在循环外部计算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) catch (Exception ex)
{ {
Log($"设置色彩模式异常 (尝试 {attempt + 1}/{maxRetries}): {ex.Message}"); Log($"获取当前色彩模式值时出错: {ex.Message}");
// 即使获取失败,仍尝试设置新值
// 简化SDK状态检查避免触发额外的UDP命令
Log($"SDK状态监控: 色彩模式设置操作失败");
// 重试前等待
Thread.Sleep(retryDelayMs);
} }
// 将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;
} }
finally
// 所有尝试都失败
Log($"色彩模式设置最终失败: 已尝试{maxRetries}次");
// 最后一次尝试失败后,仅在有原始值的情况下尝试恢复
if (originalValue >= 0 && _a8Sdk != null && _connectionStatus == ConnectionStatus.Connected)
{ {
try // 无论设置成功与否,都恢复心跳检测
if (wasHeartbeatRunning && _heartbeatTimer != null)
{ {
_a8Sdk.Color_plate = originalValue; _heartbeatTimer.Change(_heartbeatInterval, _heartbeatInterval);
Log($"已恢复原始色彩模式值: {originalValue}"); Log("设置色彩模式后恢复心跳检测");
}
catch (Exception restoreEx)
{
Log($"恢复原始色彩模式失败: {restoreEx.Message}");
} }
} }
return false;
} }
} }
@@ -3817,7 +3814,9 @@ namespace JoyD.Windows.CS.Toprie
if (heartbeatResult > 0) if (heartbeatResult > 0)
{ {
heartbeatSuccessful = true; 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) if (_connectionStatus != ConnectionStatus.Connected)
{ {
@@ -3850,13 +3849,25 @@ namespace JoyD.Windows.CS.Toprie
if (!heartbeatSuccessful) 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() - 连续心跳失败次数未达阈值,暂时保留连接状态");
} }
} }
} }

View File

@@ -31,7 +31,8 @@ namespace JoyD.Windows.CS.Toprie
{ {
SHUTTER_CORRECTION = 0, SHUTTER_CORRECTION = 0,
SET_AUTO_SHUTTER = 1, SET_AUTO_SHUTTER = 1,
SET_COLOR_PLATE = 2, // 根据热像仪SDK设置色彩模式的命令类型
SET_COLOR_PLATE = 2, // 保持为2因为热像仪SDK中也是使用SET_COLOR_PLATE命令
SET_MIRROR_VIDEO = 3, SET_MIRROR_VIDEO = 3,
SET_VIDEO_MODE = 4, SET_VIDEO_MODE = 4,
SET_AREA_POS = 5, SET_AREA_POS = 5,
@@ -46,10 +47,10 @@ namespace JoyD.Windows.CS.Toprie
SET_EMAIL_SERVER = 14, SET_EMAIL_SERVER = 14,
SET_TFTP_SERVER = 15, SET_TFTP_SERVER = 15,
SET_NETWORK_ETH = 16, SET_NETWORK_ETH = 16,
SET_FUSION_DISTANCE = 17, GET_PARAMETER = 17,
SET_ENVIR_PARAM = 18, SET_FUSION_DISTANCE = 18,
SET_ALARM_PARAM = 19, SET_ENVIR_PARAM = 19,
GET_PARAMETER = 20, SET_ALARM_PARAM = 20,
POWER_REBOOT = 21, POWER_REBOOT = 21,
PARAM_RECOVER = 22, PARAM_RECOVER = 22,
UPDATER = 23, UPDATER = 23,
@@ -273,13 +274,10 @@ namespace JoyD.Windows.CS.Toprie
try try
{ {
// 从第5个字符开始解析数值 (+RET:值$) // 从第5个字符开始解析数值与热像仪SDK保持一致
int endIndex = response.IndexOf('$'); // SDK使用atoi(buff + 5)直接解析,不检查$符号
if (endIndex > 5) string valueStr = response.Substring(5);
{ return int.Parse(valueStr);
string valueStr = response.Substring(5, endIndex - 5);
return int.Parse(valueStr);
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -637,9 +635,9 @@ namespace JoyD.Windows.CS.Toprie
{ {
Log($"[色彩模式设置] 验证成功,当前值确认为: {validatedValue}"); Log($"[色彩模式设置] 验证成功,当前值确认为: {validatedValue}");
// 设置成功后重启图像接收以避免卡顿 // 移除图像接收重启逻辑,因为色彩模式不影响图像接收
Log($"[色彩模式设置] 设置成功后重启图像接收以避免卡顿"); // 仅保留短暂延迟确保设置生效
SafeRestartImageReceiving(); Log($"[色彩模式设置] 设置成功,不需要重启图像接收");
} }
else else
{ {