diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs
index 08852cb..73b4b2d 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs
@@ -2217,6 +2217,9 @@ namespace JoyD.Windows.CS.Toprie
CurrentImageMode = mode;
}
+ // 用于保护SDK操作的线程锁
+ private readonly object _sdkOperationLock = new object();
+
///
/// 设置色彩模式
///
@@ -2224,37 +2227,114 @@ namespace JoyD.Windows.CS.Toprie
/// 设置是否成功
public bool SetPaletteType(PaletteType paletteType)
{
- try
+ // 添加线程锁保护,防止多线程同时操作SDK
+ lock (_sdkOperationLock)
{
- if (_a8Sdk != null)
+ // 最大重试次数
+ const int maxRetries = 3;
+ // 重试间隔(毫秒)
+ const int retryDelayMs = 100;
+
+ // 先获取原始值,只读取一次,避免嵌套调用
+ int originalValue = -1;
+ try
{
- // 将PaletteType枚举转换为int类型并发送命令
- // 按照SDK文档中的参数映射:白热(0)、黑热(1)、铁红(2)、熔岩(3)、彩虹(4)、铁灰(5)、红热(6)、彩虹2(7)
- int paletteValue = (int)paletteType;
-
- // 尝试设置色彩模式
- int originalValue = _a8Sdk.Color_plate; // 先获取当前值
- _a8Sdk.Color_plate = paletteValue;
-
- // 验证设置是否成功(通过再次读取确认)
- int currentValue = _a8Sdk.Color_plate;
- if (currentValue == paletteValue)
+ if (_a8Sdk != null && _connectionStatus == ConnectionStatus.Connected)
{
- Console.WriteLine($"色彩模式设置成功: {paletteType} (值: {paletteValue})");
- return true;
- }
- else
- {
- Console.WriteLine($"色彩模式设置失败: 未能确认设置生效,当前值: {currentValue}");
- return false;
+ originalValue = _a8Sdk.Color_plate;
+ Log($"成功读取当前色彩模式值: {originalValue}");
}
}
- Console.WriteLine("色彩模式设置失败: SDK实例为空");
- return false;
- }
- catch (Exception ex)
- {
- Console.WriteLine($"设置色彩模式失败: {ex.Message}");
+ catch (Exception ex)
+ {
+ Log($"获取当前色彩模式值时出错: {ex.Message}");
+ // 即使获取失败,仍尝试设置新值
+ }
+
+ for (int attempt = 0; attempt < maxRetries; attempt++)
+ {
+ try
+ {
+ // 检查对象状态和连接状态
+ if (_a8Sdk == null || _connectionStatus != ConnectionStatus.Connected)
+ {
+ Log($"色彩模式设置失败: {(attempt > 0 ? "重试中" : "")}SDK实例为空或设备未连接");
+ Thread.Sleep(retryDelayMs);
+ continue;
+ }
+
+ // 将PaletteType枚举转换为int类型并发送命令
+ // 按照SDK文档中的参数映射:白热(0)、黑热(1)、铁红(2)、熔岩(3)、彩虹(4)、铁灰(5)、红热(6)、彩虹2(7)
+ int paletteValue = (int)paletteType;
+
+ // 直接设置色彩模式,不再在每次尝试中读取原始值
+ _a8Sdk.Color_plate = paletteValue;
+
+ // 短暂延迟,确保设置生效
+ Thread.Sleep(50);
+
+ // 减少读取验证,避免嵌套UDP命令
+ // 信任SDK的设置操作,不再额外验证
+ Log($"色彩模式设置成功: {paletteType} (值: {paletteValue})");
+ 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($"色彩模式设置最终失败: 已尝试{maxRetries}次");
+
+ // 最后一次尝试失败后,仅在有原始值的情况下尝试恢复
+ if (originalValue >= 0 && _a8Sdk != null && _connectionStatus == ConnectionStatus.Connected)
+ {
+ try
+ {
+ _a8Sdk.Color_plate = originalValue;
+ Log($"已恢复原始色彩模式值: {originalValue}");
+ }
+ catch (Exception restoreEx)
+ {
+ Log($"恢复原始色彩模式失败: {restoreEx.Message}");
+ }
+ }
+
return false;
}
}
@@ -2265,20 +2345,85 @@ namespace JoyD.Windows.CS.Toprie
/// 图像模式
private bool SendModeChangeCommand(ImageMode mode)
{
- try
+ // 使用相同的线程锁保护SDK操作
+ lock (_sdkOperationLock)
{
- if (_a8Sdk != null)
+ // 最大重试次数
+ const int maxRetries = 3;
+ // 重试间隔(毫秒)
+ const int retryDelayMs = 100;
+
+ for (int attempt = 0; attempt < maxRetries; attempt++)
{
- // 将ImageMode枚举转换为int类型
- _a8Sdk.SetImageMode((int)mode);
- return true;
+ try
+ {
+ // 检查对象状态和连接状态
+ if (_a8Sdk == null || _connectionStatus != ConnectionStatus.Connected)
+ {
+ Log($"图像模式切换失败: {(attempt > 0 ? "重试中" : "")}SDK实例为空或设备未连接");
+ Thread.Sleep(retryDelayMs);
+ continue;
+ }
+
+ // 将ImageMode枚举转换为int类型
+ _a8Sdk.SetImageMode((int)mode);
+
+ // 短暂延迟,确保设置生效
+ Thread.Sleep(50);
+
+ // 简单验证:尝试读取一个基本属性确认SDK仍在正常工作
+ try
+ {
+ // 使用一个简单的只读操作验证SDK状态
+ int testValue = _a8Sdk.Color_plate; // 使用Color_plate作为验证点
+ Log($"读取色彩模式值用于验证: {testValue}");
+ Log($"图像模式 {mode} 切换成功 (尝试 {attempt + 1}/{maxRetries})");
+ return true;
+ }
+ catch (Exception verifyEx)
+ {
+ // 验证失败,记录日志并准备重试
+ Log($"图像模式切换验证失败 (尝试 {attempt + 1}/{maxRetries}): {verifyEx.Message}");
+
+ // 重试前等待
+ Thread.Sleep(retryDelayMs);
+ continue;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log($"切换图像模式异常 (尝试 {attempt + 1}/{maxRetries}): {ex.Message}");
+
+ // 增加SDK状态检查,判断是否真的需要触发连接异常
+ try
+ {
+ // 简单的SDK状态检查
+ if (_a8Sdk != null)
+ {
+ // 只读操作,确认SDK仍在响应
+ int testValue = _a8Sdk.Color_plate;
+ Log($"SDK状态检查: 读取色彩模式值 = {testValue}");
+ }
+ }
+ catch (Exception checkEx)
+ {
+ Log($"SDK状态检查失败: {checkEx.Message}");
+
+ // 只有在最后一次尝试且确认SDK状态异常时,才触发连接异常
+ if (attempt == maxRetries - 1)
+ {
+ Log("所有尝试失败且SDK状态异常,触发连接异常事件");
+ OnConnectionException(new ConnectionExceptionEventArgs(checkEx, "图像模式切换导致SDK状态异常"));
+ }
+ }
+
+ // 重试前等待
+ Thread.Sleep(retryDelayMs);
+ }
}
- return false;
- }
- catch (Exception ex)
- {
- Console.WriteLine($"切换图像模式失败: {ex.Message}");
- OnConnectionException(new ConnectionExceptionEventArgs(ex, "切换图像模式失败"));
+
+ // 所有尝试都失败
+ Log($"图像模式切换最终失败: 已尝试{maxRetries}次");
return false;
}
}
@@ -2288,7 +2433,7 @@ namespace JoyD.Windows.CS.Toprie
///
public void StartReceiveImage()
{
- Console.WriteLine("已弃用的StartReceiveImage方法,自动切换到HTTP方式");
+ Log("已弃用的StartReceiveImage方法,自动切换到HTTP方式");
if (_connectionStatus != ConnectionStatus.Connected)
{