解决探测器退出阻塞的问题,中加入超时保护,避免死锁。

This commit is contained in:
QI Mingxuan
2026-05-11 13:27:44 +08:00
parent c1c2b93cf8
commit 8666c76f65
@@ -570,17 +570,72 @@ namespace XP.Hardware.Detector.Services
{
if (disposing)
{
// 停止采集(如果正在采集)| Stop acquisition if acquiring
StopAcquisitionAsync().GetAwaiter().GetResult();
// 带超时保护的资源释放,避免退出时无限阻塞
// Dispose with timeout protection to avoid infinite blocking on exit
const int disposeTimeoutMs = 5000; // 5 秒总超时 | 5 seconds total timeout
// 断开探测器连接 | Disconnect detector
DisconnectAsync().GetAwaiter().GetResult();
// 释放托管资源 | Release managed resources
lock (_lock)
try
{
_detector?.Dispose();
_detector = null;
IAreaDetector detector;
lock (_lock)
{
detector = _detector;
}
if (detector != null)
{
// 仅在正在采集时才停止采集 | Only stop acquisition if currently acquiring
if (detector.Status == DetectorStatus.Acquiring)
{
_logger?.Info("Dispose:探测器正在采集,尝试停止 | Dispose: Detector is acquiring, attempting to stop");
using var cts = new CancellationTokenSource(disposeTimeoutMs);
var stopTask = Task.Run(async () => await detector.StopAcquisitionAsync(cts.Token), cts.Token);
if (!stopTask.Wait(disposeTimeoutMs))
{
_logger?.Warn("Dispose:停止采集超时,强制继续释放 | Dispose: Stop acquisition timeout, forcing cleanup");
}
}
// 直接释放探测器资源(不再调用 DisconnectAsync 避免重复停止)
// Directly dispose detector resources (skip DisconnectAsync to avoid redundant stop)
lock (_lock)
{
_detector?.Dispose();
_detector = null;
}
_config = null;
_logger?.Info("Dispose:探测器资源已释放 | Dispose: Detector resources disposed");
}
}
catch (OperationCanceledException)
{
_logger?.Warn("Dispose:操作已取消,强制释放资源 | Dispose: Operation cancelled, forcing resource cleanup");
lock (_lock)
{
_detector?.Dispose();
_detector = null;
}
_config = null;
}
catch (AggregateException ex)
{
_logger?.Warn($"Dispose:聚合异常,强制释放资源 | Dispose: Aggregate exception, forcing cleanup: {ex.InnerException?.Message ?? ex.Message}");
lock (_lock)
{
_detector?.Dispose();
_detector = null;
}
_config = null;
}
catch (Exception ex)
{
_logger?.Error(ex, "Dispose:释放探测器资源异常 | Dispose: Exception disposing detector resources");
lock (_lock)
{
try { _detector?.Dispose(); } catch { /* 忽略 | Ignore */ }
_detector = null;
}
_config = null;
}
}
_disposed = true;