优化菜单显示和SDK实例管理:1. 菜单仅在连接成功时显示 2. 增强多线程环境下的SDK实例访问安全性

This commit is contained in:
zqm
2025-10-30 15:49:10 +08:00
parent acc2509005
commit 63ebe4faa1
2 changed files with 93 additions and 28 deletions

View File

@@ -1169,9 +1169,12 @@ namespace JoyD.Windows.CS.Toprie
// 检查是否处于暂停状态
bool isPaused = pauseDetectionToolStripMenuItem.Text == "恢复检测";
// 在暂停状态下,隐藏图像模式根菜单和色彩模式菜单
// 检查设备是否已连接
bool isConnected = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected;
// 在暂停状态或未连接状态下,隐藏图像模式根菜单和色彩模式菜单
// 注意:根菜单隐藏后,其所有子菜单会自动隐藏,不需要单独设置
if (isPaused)
if (isPaused || !isConnected)
{
// 隐藏图像模式根菜单
if (imageModeToolStripMenuItem != null)
@@ -1185,20 +1188,16 @@ namespace JoyD.Windows.CS.Toprie
}
else
{
// 在非暂停状态下,显示图像模式根菜单
// 在非暂停状态且已连接状态下,显示图像模式根菜单
// 注意:根菜单显示后,其所有子菜单会自动显示,不需要单独设置
if (imageModeToolStripMenuItem != null)
imageModeToolStripMenuItem.Visible = true;
// 在非暂停状态下,显示分隔符
// 在非暂停状态且已连接状态下,显示分隔符
toolStripSeparator1.Visible = true;
// 根据当前图像模式控制色彩模式菜单的可见性
if (_deviceManager != null)
{
colorModeToolStripMenuItem.Visible = _deviceManager.CurrentImageMode == ImageMode.Infrared;
}
colorModeToolStripMenuItem.Visible = _deviceManager.CurrentImageMode == ImageMode.Infrared;
// 清除视频模式菜单项的选中状态
thermalModeToolStripMenuItem.Checked = false;
visibleModeToolStripMenuItem.Checked = false;

View File

@@ -2459,29 +2459,52 @@ namespace JoyD.Windows.CS.Toprie
{
try
{
// 确保设备已连接且SDK实例有效
if (_connectionStatus == ConnectionStatus.Connected && _a8Sdk != null)
// 使用SDK操作锁保护对_a8Sdk的访问
lock (_sdkOperationLock)
{
// 获取当前设备的色彩模式值
int currentValue = _a8Sdk.GetColorPlate();
Log($"从设备读取的色彩模式值: {currentValue}");
// 尝试将读取到的值转换为PaletteType枚举并更新内部状态
if (Enum.IsDefined(typeof(PaletteType), currentValue))
// 确保设备已连接且SDK实例有效
if (_connectionStatus == ConnectionStatus.Connected && _a8Sdk != null)
{
PaletteType actualPalette = (PaletteType)currentValue;
_currentPaletteType = actualPalette;
Log($"已更新内部状态为设备实际值: {actualPalette}");
try
{
// 获取当前设备的色彩模式值
int currentValue = _a8Sdk.GetColorPlate();
Log($"从设备读取的色彩模式值: {currentValue}");
// 尝试将读取到的值转换为PaletteType枚举并更新内部状态
if (Enum.IsDefined(typeof(PaletteType), currentValue))
{
PaletteType actualPalette = (PaletteType)currentValue;
_currentPaletteType = actualPalette;
Log($"已更新内部状态为设备实际值: {actualPalette}");
}
else
{
Log($"警告:设备返回的色彩模式值 {currentValue} 不在枚举定义范围内,使用默认值");
}
}
catch (Exception ex)
{
Log($"从设备读取色彩模式时出错: {ex.Message}");
// 尝试重新创建SDK实例
Log("尝试重新创建SDK实例...");
try
{
_a8Sdk = new A8SDK(_deviceIp);
Log("SDK实例已重新创建");
}
catch (Exception recreateEx)
{
Log($"重新创建SDK实例失败: {recreateEx.Message}");
}
throw;
}
}
else
{
Log($"警告:设备返回的色彩模式值 {currentValue} 不在枚举定义范围内,使用默认值");
Log($"同步色彩模式失败设备未连接或SDK未初始化");
}
}
else
{
Log($"同步色彩模式失败设备未连接或SDK未初始化");
}
}
catch (Exception ex)
{
@@ -2515,11 +2538,27 @@ namespace JoyD.Windows.CS.Toprie
// 重试间隔(毫秒)
const int retryDelayMs = 100;
// 确保SDK实例存在如果不存在则尝试创建
if (_a8Sdk == null)
{
Log("SDK实例为空尝试创建新实例...");
try
{
_a8Sdk = new A8SDK(_deviceIp);
Log("SDK实例创建成功");
}
catch (Exception ex)
{
Log($"创建SDK实例失败: {ex.Message}");
return false;
}
}
// 先获取原始值,只读取一次,避免嵌套调用
int originalValue = -1;
try
{
if (_a8Sdk != null && _connectionStatus == ConnectionStatus.Connected)
if (_connectionStatus == ConnectionStatus.Connected)
{
originalValue = _a8Sdk.Color_plate;
Log($"成功读取当前色彩模式值: {originalValue}");
@@ -2528,6 +2567,17 @@ namespace JoyD.Windows.CS.Toprie
catch (Exception ex)
{
Log($"获取当前色彩模式值时出错: {ex.Message}");
// 尝试重新创建SDK实例
Log("尝试重新创建SDK实例...");
try
{
_a8Sdk = new A8SDK(_deviceIp);
Log("SDK实例已重新创建");
}
catch (Exception recreateEx)
{
Log($"重新创建SDK实例失败: {recreateEx.Message}");
}
// 即使获取失败,仍尝试设置新值
}
@@ -2545,8 +2595,24 @@ namespace JoyD.Windows.CS.Toprie
{
try
{
// 检查对象状态和连接状态
if (_a8Sdk == null || _connectionStatus != ConnectionStatus.Connected)
// 再次确保SDK实例存在
if (_a8Sdk == null)
{
Log("SDK实例为空尝试重新创建...");
try
{
_a8Sdk = new A8SDK(_deviceIp);
Log("SDK实例重新创建成功");
}
catch (Exception ex)
{
Log($"重新创建SDK实例失败: {ex.Message}");
continue; // 继续下一次尝试
}
}
// 检查连接状态
if (_connectionStatus != ConnectionStatus.Connected)
{
Log($"色彩模式设置失败: {(attempt > 0 ? "" : "")}SDK实例为空或设备未连接");
Thread.Sleep(retryDelayMs);