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) {