解决设备不存在时的卡顿问题

This commit is contained in:
zqm
2026-01-06 09:56:59 +08:00
parent 9ee598cc49
commit 87dee33c76
2 changed files with 41 additions and 37 deletions

View File

@@ -83,6 +83,10 @@ namespace JoyD.Windows.CS.Toprie
// 是否暂停检测
private bool _isPaused = false;
/// <summary>
/// 首次ping通设备并更新信息
/// </summary>
private volatile bool _isFirst = true;
// 项目路径,用于数据文件的存取
private string _projectPath = "";
@@ -557,6 +561,18 @@ namespace JoyD.Windows.CS.Toprie
{
// 只有在非设计模式下才启动相机
if (!DesignMode)
{
try
{
// 启动设备Ping
StartDevicePing();
// 延迟启动相机,避免界面卡顿
ThreadPool.QueueUserWorkItem(delegate
{
while(!IsDevicePingable)
Thread.Sleep(3000); // 延迟3秒后启动
_isFirst = false;
this.Invoke(new Action(() =>
{
try
{
@@ -566,6 +582,13 @@ namespace JoyD.Windows.CS.Toprie
{
ShowError($"自动启动相机失败: {ex.Message}");
}
}));
});
}
catch (Exception ex)
{
ShowError($"启动相机失败: {ex.Message}");
}
}
}
@@ -694,8 +717,6 @@ namespace JoyD.Windows.CS.Toprie
/// </summary>
public void StartCamera()
{
// 启动设备Ping
StartDevicePing();
if (DesignMode) return;
try
{
@@ -949,7 +970,6 @@ namespace JoyD.Windows.CS.Toprie
}
catch (ObjectDisposedException)
{
Console.WriteLine("控件已释放跳过UI更新");
}
return;
}
@@ -963,7 +983,7 @@ namespace JoyD.Windows.CS.Toprie
// 调用温度显示更新方法
// 在就绪条件下,调用更新实时信息
bool isReady = !_isPaused && IsDevicePingable && _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected;
bool isReady = _deviceManager != null && (_isFirst || (!_isPaused && IsDevicePingable && _deviceManager.ConnectionStatus == ConnectionStatus.Connected));
if (isReady)
{
UpdateRealTimeInfoOnUI();
@@ -979,11 +999,9 @@ namespace JoyD.Windows.CS.Toprie
// 检查图像缓冲区是否有效
if (_imageBuffer == null)
{
Console.WriteLine("图像缓冲区未初始化,尝试重新初始化");
InitializeImageBuffer();
if (_imageBuffer == null)
{
Console.WriteLine("重新初始化图像缓冲区失败");
return;
}
}
@@ -991,12 +1009,17 @@ namespace JoyD.Windows.CS.Toprie
// 保存旧图像引用,以便在设置新图像后释放
oldImage = imageBox.Image;
if (!_isFirst)
{
// 获取当前的LastImage引用
lock (_lastImageLock)
{
if (_lastImage != null)
if (_lastImage == null)
{
lastImage = (Image)_lastImage.Clone();
return;
}
// 直接使用_lastImage引用避免创建不必要的副本
lastImage = _lastImage;
}
}
@@ -1005,7 +1028,8 @@ namespace JoyD.Windows.CS.Toprie
{
if (_infoImage != null)
{
infoImage = (Image)_infoImage.Clone();
// 直接使用_infoImage引用避免创建不必要的副本
infoImage = _infoImage;
}
}
@@ -1090,7 +1114,6 @@ namespace JoyD.Windows.CS.Toprie
{
// 特别处理"参数无效"异常
Console.WriteLine($"图像参数无效异常: {ex.Message}");
// 尝试设置旧图像回来,不需要再次检查控件状态(已在方法开始处检查)
if (oldImage != null)
{
@@ -1146,25 +1169,15 @@ namespace JoyD.Windows.CS.Toprie
return;
}
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 接收连接状态变更事件: {e.Status}");
// 捕获所有可能的异常,确保事件处理器不会崩溃
try
{
// 首先检查控件状态
if (this.IsDisposed || this.Disposing)
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 控件已释放或正在释放跳过UI更新");
return;
}
// 检查事件参数中的状态信息
string statusMessage = $"连接状态变更为: {e.Status}";
if (!string.IsNullOrEmpty(e.DeviceInfo))
{
statusMessage += $" (设备信息: {e.DeviceInfo})";
}
// 线程安全处理 - 确保在UI线程上更新
if (this.InvokeRequired)
{
@@ -1178,10 +1191,6 @@ namespace JoyD.Windows.CS.Toprie
{
HandleConnectionStatusChanged(args);
}
else
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 异步调用期间控件已释放,跳过处理");
}
}), e);
}
catch (ObjectDisposedException ode)
@@ -1220,7 +1229,7 @@ namespace JoyD.Windows.CS.Toprie
// 确保在UI线程上更新UI
if (this.InvokeRequired)
{
this.Invoke(new Action<ConnectionStatusChangedEventArgs>(HandleConnectionStatusChanged), e);
this.BeginInvoke(new Action<ConnectionStatusChangedEventArgs>(HandleConnectionStatusChanged), e);
return;
}
@@ -1230,14 +1239,9 @@ namespace JoyD.Windows.CS.Toprie
// 检查_deviceManager是否为空
if (_deviceManager == null)
{
Console.WriteLine("设备管理器未初始化");
WriteLog("设备管理器未初始化");
return;
}
// 记录连接状态变化
WriteLog($"连接状态变化: {e.Status} {(!string.IsNullOrEmpty(e.DeviceInfo) ? "- " + e.DeviceInfo : "")}");
switch (e.Status)
{
case ConnectionStatus.Connected:
@@ -1869,7 +1873,7 @@ namespace JoyD.Windows.CS.Toprie
// 在线程安全的方式下更新状态
if (this.InvokeRequired)
{
this.Invoke(new Action<bool>(UpdatePingState), pingResult);
this.BeginInvoke(new Action<bool>(UpdatePingState), pingResult);
}
else
{

View File

@@ -32,7 +32,7 @@ using System.Runtime.InteropServices;
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.3")]
[assembly: AssemblyFileVersion("1.0.0.7")]
[assembly: AssemblyVersion("1.0.1.0")]
[assembly: AssemblyFileVersion("1.0.1.0")]
// NuGet包相关信息已在项目文件中配置