# 探测器模块使用指南 | Detector Module Usage Guide

## 1. 模块概述 | Module Overview

XP.Hardware.Detector 是 XplorePlane X 射线检测系统的探测器控制模块，负责与工业 X 射线探测器进行通讯和控制。该模块采用策略模式设计，支持多种探测器型号的统一管理。

### 核心特性 | Key Features

- 支持多种探测器型号（Varex、iRay 等）
- 完整的探测器生命周期管理（初始化、采集、校正）
- 单帧和连续采集模式
- 自动校正功能（暗场、增益、坏像素）
- 实时状态监控
- 基于 Prism 事件聚合器的松耦合通讯
- 异步操作，不阻塞 UI 线程

---

## 2. 模块注册 | Module Registration

探测器模块通过 Prism 的模块化系统注册，在应用启动时自动加载。

### 在 App.xaml.cs 中注册

```csharp
using Prism.Modularity;
using XP.Hardware.Detector.Module;

protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
    // 注册探测器模块 | Register Detector module
    moduleCatalog.AddModule<DetectorModule>();
    
    base.ConfigureModuleCatalog(moduleCatalog);
}
```

### 模块自动注册的服务

- `IDetectorFactory` - 探测器工厂（瞬态）
- `IDetectorService` - 探测器业务服务（单例）

---

## 3. 配置文件设置 | Configuration File Setup

在 `App.config` 中添加探测器配置：

```xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <!-- 探测器类型 | Detector Type -->
    <add key="Detector:Type" value="Varex" />
    
    <!-- 网络配置 | Network Configuration -->
    <add key="Detector:IP" value="192.168.1.200" />
    <add key="Detector:Port" value="50000" />
    
    <!-- 图像存储配置 | Image Storage Configuration -->
    <add key="Detector:SavePath" value="D:\Images" />
    <add key="Detector:AutoSave" value="true" />
    
    <!-- Varex 探测器特定配置 | Varex Detector Specific Configuration -->
    <add key="Varex:ConfigFile" value="detector.xml" />
    <add key="Varex:CalibrationFile" value="calibration.cal" />
    
    <!-- iRay 探测器特定配置 | iRay Detector Specific Configuration -->
    <add key="IRay:DeviceID" value="0" />
    <add key="IRay:ExposureTime" value="100" />
  </appSettings>
</configuration>
```

### 配置参数说明

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| Type | string | Varex | 探测器类型（Varex/IRay）|
| IP | string | 192.168.1.200 | 探测器 IP 地址 |
| Port | int | 50000 | 探测器端口号 |
| SavePath | string | D:\Images | 图像存储路径 |
| AutoSave | bool | true | 是否自动保存图像 |

---
## 4. 在 ViewModel 中使用 | Usage in ViewModel

### 4.1 注入服务

```csharp
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using System.Threading.Tasks;
using XP.Common.Logging.Interfaces;
using XP.Hardware.Detector.Abstractions;
using XP.Hardware.Detector.Abstractions.Enums;
using XP.Hardware.Detector.Abstractions.Events;
using XP.Hardware.Detector.Services;

namespace YourNamespace.ViewModels
{
    public class YourViewModel : BindableBase
    {
        private readonly IDetectorService _detectorService;
        private readonly IEventAggregator _eventAggregator;
        private readonly ILoggerService _logger;

        /// <summary>
        /// 构造函数，通过依赖注入获取服务 | Constructor with dependency injection
        /// </summary>
        public YourViewModel(
            IDetectorService detectorService,
            IEventAggregator eventAggregator,
            ILoggerService logger)
        {
            _detectorService = detectorService;
            _eventAggregator = eventAggregator;
            _logger = logger.ForModule("YourViewModel");
            
            // 订阅事件 | Subscribe to events
            SubscribeEvents();
        }
        
        private void SubscribeEvents()
        {
            // 订阅图像采集事件 | Subscribe to image captured event
            _eventAggregator.GetEvent<ImageCapturedEvent>()
                .Subscribe(OnImageCaptured);
            
            // 订阅校正完成事件 | Subscribe to correction completed event
            _eventAggregator.GetEvent<CorrectionCompletedEvent>()
                .Subscribe(OnCorrectionCompleted);
        }
        
        private void OnImageCaptured(ImageCapturedEventArgs args)
        {
            _logger.Info($"图像已采集: {args.FrameNumber}");
        }
        
        private void OnCorrectionCompleted(CorrectionCompletedEventArgs args)
        {
            _logger.Info($"校正完成: {args.CorrectionType}");
        }
    }
}
```

### 4.2 初始化探测器

```csharp
/// <summary>
/// 初始化探测器 | Initialize detector
/// </summary>
public async Task InitializeDetectorAsync()
{
    try
    {
        _logger.Info("开始初始化探测器... | Starting detector initialization...");
        StatusMessage = "正在初始化... | Initializing...";
        
        DetectorResult result = await _detectorService.InitializeAsync();
        
        if (result.IsSuccess)
        {
            _logger.Info("探测器初始化成功 | Detector initialized successfully");
            StatusMessage = "探测器已就绪 | Detector ready";
            
            // 获取探测器信息 | Get detector information
            DetectorInfo info = _detectorService.GetInfo();
            _logger.Info($"探测器型号: {info.Model}, 分辨率: {info.MaxWidth}x{info.MaxHeight}");
        }
        else
        {
            _logger.Error(null, $"探测器初始化失败: {result.ErrorMessage}");
            StatusMessage = $"初始化失败: {result.ErrorMessage}";
        }
    }
    catch (Exception ex)
    {
        _logger.Error(ex, $"初始化异常: {ex.Message}");
        StatusMessage = $"初始化异常: {ex.Message}";
    }
}
```

### 4.3 单帧采集

```csharp
/// <summary>
/// 单帧采集 | Single frame acquisition
/// </summary>
public async Task AcquireSingleFrameAsync()
{
    try
    {
        if (_detectorService.Status != DetectorStatus.Ready)
        {
            _logger.Warn("探测器未就绪，无法采集");
            StatusMessage = "探测器未就绪 | Detector not ready";
            return;
        }
        
        _logger.Info("开始单帧采集... | Starting single frame acquisition...");
        StatusMessage = "正在采集... | Acquiring...";
        
        DetectorResult result = await _detectorService.AcquireSingleFrameAsync();
        
        if (result.IsSuccess)
        {
            _logger.Info("单帧采集成功 | Single frame acquired successfully");
            StatusMessage = "采集完成 | Acquisition completed";
        }
        else
        {
            _logger.Error(null, $"单帧采集失败: {result.ErrorMessage}");
            StatusMessage = $"采集失败: {result.ErrorMessage}";
        }
    }
    catch (Exception ex)
    {
        _logger.Error(ex, $"单帧采集异常: {ex.Message}");
        StatusMessage = $"采集异常: {ex.Message}";
    }
}
```

### 4.4 启动连续采集

```csharp
/// <summary>
/// 启动连续采集 | Start continuous acquisition
/// </summary>
public async Task StartAcquisitionAsync()
{
    try
    {
        if (_detectorService.Status != DetectorStatus.Ready)
        {
            _logger.Warn("探测器未就绪，无法启动采集");
            return;
        }
        
        _logger.Info("启动连续采集... | Starting continuous acquisition...");
        StatusMessage = "连续采集中... | Continuous acquisition...";
        
        DetectorResult result = await _detectorService.StartAcquisitionAsync();
        
        if (result.IsSuccess)
        {
            _logger.Info("连续采集已启动 | Continuous acquisition started");
            IsAcquiring = true;
        }
        else
        {
            _logger.Error(null, $"启动采集失败: {result.ErrorMessage}");
            StatusMessage = $"启动失败: {result.ErrorMessage}";
        }
    }
    catch (Exception ex)
    {
        _logger.Error(ex, $"启动采集异常: {ex.Message}");
        StatusMessage = $"启动异常: {ex.Message}";
    }
}
```

### 4.5 停止采集

```csharp
/// <summary>
/// 停止采集 | Stop acquisition
/// </summary>
public async Task StopAcquisitionAsync()
{
    try
    {
        _logger.Info("停止采集... | Stopping acquisition...");
        StatusMessage = "正在停止... | Stopping...";
        
        DetectorResult result = await _detectorService.StopAcquisitionAsync();
        
        if (result.IsSuccess)
        {
            _logger.Info("采集已停止 | Acquisition stopped");
            StatusMessage = "已停止 | Stopped";
            IsAcquiring = false;
        }
        else
        {
            _logger.Error(null, $"停止采集失败: {result.ErrorMessage}");
            StatusMessage = $"停止失败: {result.ErrorMessage}";
        }
    }
    catch (Exception ex)
    {
        _logger.Error(ex, $"停止采集异常: {ex.Message}");
        StatusMessage = $"停止异常: {ex.Message}";
    }
}
```

---
## 5. 校正功能 | Correction Functions

### 5.1 自动校正

```csharp
/// <summary>
/// 执行自动校正（暗场+增益+坏像素）| Execute auto correction (dark + gain + bad pixel)
/// </summary>
/// <param name="frameCount">采集帧数 | Frame count</param>
public async Task AutoCorrectionAsync(int frameCount = 10)
{
    try
    {
        _logger.Info($"开始自动校正，帧数: {frameCount} | Starting auto correction, frames: {frameCount}");
        StatusMessage = "正在校正... | Correcting...";
        
        DetectorResult result = await _detectorService.AutoCorrectionAsync(frameCount);
        
        if (result.IsSuccess)
        {
            _logger.Info("自动校正完成 | Auto correction completed");
            StatusMessage = "校正完成 | Correction completed";
        }
        else
        {
            _logger.Error(null, $"自动校正失败: {result.ErrorMessage}");
            StatusMessage = $"校正失败: {result.ErrorMessage}";
        }
    }
    catch (Exception ex)
    {
        _logger.Error(ex, $"自动校正异常: {ex.Message}");
        StatusMessage = $"校正异常: {ex.Message}";
    }
}
```

### 5.2 获取探测器信息

```csharp
/// <summary>
/// 获取探测器信息 | Get detector information
/// </summary>
public void GetDetectorInfo()
{
    try
    {
        DetectorInfo info = _detectorService.GetInfo();
        
        if (info != null)
        {
            _logger.Info($"探测器信息:");
            _logger.Info($"  型号: {info.Model}");
            _logger.Info($"  序列号: {info.SerialNumber}");
            _logger.Info($"  固件版本: {info.FirmwareVersion}");
            _logger.Info($"  分辨率: {info.MaxWidth}x{info.MaxHeight}");
            _logger.Info($"  像素尺寸: {info.PixelSize}μm");
            _logger.Info($"  位深度: {info.BitDepth}bit");
            
            // 更新 UI 显示 | Update UI display
            DetectorModel = info.Model;
            Resolution = $"{info.MaxWidth}x{info.MaxHeight}";
            PixelSize = $"{info.PixelSize}μm";
        }
    }
    catch (Exception ex)
    {
        _logger.Error(ex, $"获取探测器信息异常: {ex.Message}");
    }
}
```

---

## 6. Prism 事件通讯 | Prism Event Communication

模块使用 Prism 事件聚合器实现跨模块通讯，支持以下事件：

### 6.1 图像采集事件

```csharp
// 订阅图像采集事件 | Subscribe to image captured event
_eventAggregator.GetEvent<ImageCapturedEvent>()
    .Subscribe(OnImageCaptured, ThreadOption.UIThread);

private void OnImageCaptured(ImageCapturedEventArgs args)
{
    // args.FrameNumber - 帧编号
    // args.Timestamp - 时间戳
    // args.ImageData - 图像数据（如果有）
    
    FrameNumber = args.FrameNumber;
    LastCaptureTime = args.Timestamp;
    
    _logger.Info($"图像已采集: 帧 {args.FrameNumber}");
}
```

### 6.2 校正完成事件

```csharp
// 订阅校正完成事件 | Subscribe to correction completed event
_eventAggregator.GetEvent<CorrectionCompletedEvent>()
    .Subscribe(OnCorrectionCompleted, ThreadOption.UIThread);

private void OnCorrectionCompleted(CorrectionCompletedEventArgs args)
{
    // args.CorrectionType - 校正类型（暗场/增益/坏像素）
    // args.IsSuccess - 是否成功
    // args.Message - 消息
    
    if (args.IsSuccess)
    {
        _logger.Info($"校正完成: {args.CorrectionType}");
        StatusMessage = $"{args.CorrectionType} 校正完成";
    }
    else
    {
        _logger.Error(null, $"校正失败: {args.Message}");
        StatusMessage = $"校正失败: {args.Message}";
    }
}
```

---

## 7. 完整示例 | Complete Example

```csharp
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
using XP.Common.Logging.Interfaces;
using XP.Hardware.Detector.Abstractions;
using XP.Hardware.Detector.Abstractions.Enums;
using XP.Hardware.Detector.Abstractions.Events;
using XP.Hardware.Detector.Services;

namespace YourNamespace.ViewModels
{
    public class DetectorControlViewModel : BindableBase
    {
        private readonly IDetectorService _detectorService;
        private readonly IEventAggregator _eventAggregator;
        private readonly ILoggerService _logger;

        #region 属性 | Properties

        private string _statusMessage;
        public string StatusMessage
        {
            get => _statusMessage;
            set => SetProperty(ref _statusMessage, value);
        }

        private DetectorStatus _detectorStatus;
        public DetectorStatus DetectorStatus
        {
            get => _detectorStatus;
            set => SetProperty(ref _detectorStatus, value);
        }

        private bool _isAcquiring;
        public bool IsAcquiring
        {
            get => _isAcquiring;
            set => SetProperty(ref _isAcquiring, value);
        }

        private int _frameNumber;
        public int FrameNumber
        {
            get => _frameNumber;
            set => SetProperty(ref _frameNumber, value);
        }

        private string _detectorModel;
        public string DetectorModel
        {
            get => _detectorModel;
            set => SetProperty(ref _detectorModel, value);
        }

        private string _resolution;
        public string Resolution
        {
            get => _resolution;
            set => SetProperty(ref _resolution, value);
        }

        #endregion

        #region 命令 | Commands

        public ICommand InitializeCommand { get; }
        public ICommand AcquireSingleFrameCommand { get; }
        public ICommand StartAcquisitionCommand { get; }
        public ICommand StopAcquisitionCommand { get; }
        public ICommand AutoCorrectionCommand { get; }
        public ICommand GetInfoCommand { get; }

        #endregion

        public DetectorControlViewModel(
            IDetectorService detectorService,
            IEventAggregator eventAggregator,
            ILoggerService logger)
        {
            _detectorService = detectorService;
            _eventAggregator = eventAggregator;
            _logger = logger.ForModule("DetectorControlViewModel");

            // 初始化命令 | Initialize commands
            InitializeCommand = new DelegateCommand(async () => await InitializeAsync());
            AcquireSingleFrameCommand = new DelegateCommand(async () => await AcquireSingleFrameAsync(), CanAcquire)
                .ObservesProperty(() => DetectorStatus);
            StartAcquisitionCommand = new DelegateCommand(async () => await StartAcquisitionAsync(), CanStartAcquisition)
                .ObservesProperty(() => DetectorStatus)
                .ObservesProperty(() => IsAcquiring);
            StopAcquisitionCommand = new DelegateCommand(async () => await StopAcquisitionAsync(), CanStopAcquisition)
                .ObservesProperty(() => IsAcquiring);
            AutoCorrectionCommand = new DelegateCommand(async () => await AutoCorrectionAsync(), CanCorrect)
                .ObservesProperty(() => DetectorStatus);
            GetInfoCommand = new DelegateCommand(GetInfo);

            // 订阅事件 | Subscribe to events
            SubscribeEvents();
        }

        #region 命令实现 | Command Implementations

        private async Task InitializeAsync()
        {
            try
            {
                StatusMessage = "正在初始化... | Initializing...";
                DetectorResult result = await _detectorService.InitializeAsync();
                
                if (result.IsSuccess)
                {
                    DetectorStatus = _detectorService.Status;
                    StatusMessage = "探测器已就绪 | Detector ready";
                    GetInfo();
                }
                else
                {
                    StatusMessage = $"初始化失败: {result.ErrorMessage}";
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "初始化异常");
                StatusMessage = $"初始化异常: {ex.Message}";
            }
        }

        private async Task AcquireSingleFrameAsync()
        {
            try
            {
                StatusMessage = "正在采集... | Acquiring...";
                DetectorResult result = await _detectorService.AcquireSingleFrameAsync();
                
                if (result.IsSuccess)
                {
                    StatusMessage = "采集完成 | Acquisition completed";
                }
                else
                {
                    StatusMessage = $"采集失败: {result.ErrorMessage}";
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "单帧采集异常");
                StatusMessage = $"采集异常: {ex.Message}";
            }
        }

        private async Task StartAcquisitionAsync()
        {
            try
            {
                StatusMessage = "启动连续采集... | Starting continuous acquisition...";
                DetectorResult result = await _detectorService.StartAcquisitionAsync();
                
                if (result.IsSuccess)
                {
                    IsAcquiring = true;
                    DetectorStatus = _detectorService.Status;
                    StatusMessage = "连续采集中... | Continuous acquisition...";
                }
                else
                {
                    StatusMessage = $"启动失败: {result.ErrorMessage}";
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "启动采集异常");
                StatusMessage = $"启动异常: {ex.Message}";
            }
        }

        private async Task StopAcquisitionAsync()
        {
            try
            {
                StatusMessage = "正在停止... | Stopping...";
                DetectorResult result = await _detectorService.StopAcquisitionAsync();
                
                if (result.IsSuccess)
                {
                    IsAcquiring = false;
                    DetectorStatus = _detectorService.Status;
                    StatusMessage = "已停止 | Stopped";
                }
                else
                {
                    StatusMessage = $"停止失败: {result.ErrorMessage}";
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "停止采集异常");
                StatusMessage = $"停止异常: {ex.Message}";
            }
        }

        private async Task AutoCorrectionAsync()
        {
            try
            {
                StatusMessage = "正在校正... | Correcting...";
                DetectorResult result = await _detectorService.AutoCorrectionAsync(10);
                
                if (result.IsSuccess)
                {
                    StatusMessage = "校正完成 | Correction completed";
                }
                else
                {
                    StatusMessage = $"校正失败: {result.ErrorMessage}";
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "自动校正异常");
                StatusMessage = $"校正异常: {ex.Message}";
            }
        }

        private void GetInfo()
        {
            try
            {
                DetectorInfo info = _detectorService.GetInfo();
                if (info != null)
                {
                    DetectorModel = info.Model;
                    Resolution = $"{info.MaxWidth}x{info.MaxHeight}";
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "获取信息异常");
            }
        }

        #endregion

        #region 命令条件 | Command Conditions

        private bool CanAcquire() => DetectorStatus == DetectorStatus.Ready;
        private bool CanStartAcquisition() => DetectorStatus == DetectorStatus.Ready && !IsAcquiring;
        private bool CanStopAcquisition() => IsAcquiring;
        private bool CanCorrect() => DetectorStatus == DetectorStatus.Ready;

        #endregion

        #region 事件处理 | Event Handlers

        private void SubscribeEvents()
        {
            _eventAggregator.GetEvent<ImageCapturedEvent>()
                .Subscribe(OnImageCaptured, ThreadOption.UIThread);
            
            _eventAggregator.GetEvent<CorrectionCompletedEvent>()
                .Subscribe(OnCorrectionCompleted, ThreadOption.UIThread);
        }

        private void OnImageCaptured(ImageCapturedEventArgs args)
        {
            FrameNumber = args.FrameNumber;
        }

        private void OnCorrectionCompleted(CorrectionCompletedEventArgs args)
        {
            if (args.IsSuccess)
            {
                StatusMessage = $"{args.CorrectionType} 校正完成";
            }
        }

        #endregion
    }
}
```

---
## 8. 在应用退出时释放资源 | Release Resources on Application Exit

在 `App.xaml.cs` 的 `OnExit` 方法中添加：

```csharp
protected override void OnExit(ExitEventArgs e)
{
    // 记录应用退出日志 | Log application exit
    Log.Information("XplorePlane主应用退出（XP.App-OnExit）");

    // 释放探测器资源 | Release detector resources
    try
    {
        var detectorService = Container.Resolve<IDetectorService>();
        // 探测器服务会在 Dispose 时自动停止采集和释放资源
        // Detector service will automatically stop acquisition and release resources on Dispose
        Log.Information("探测器资源已成功释放 | Detector resources released successfully");
    }
    catch (Exception ex)
    {
        Log.Error(ex, "探测器资源释放失败，忽略该错误继续退出 | Failed to release detector resources");
    }

    // 释放其他资源... | Release other resources...
    
    // 释放Serilog资源（避免日志丢失）| Release Serilog resources
    Log.CloseAndFlush();

    base.OnExit(e);
}
```

---

## 9. 探测器状态 | Detector Status

### 9.1 状态枚举

```csharp
public enum DetectorStatus
{
    Uninitialized = 0,  // 未初始化
    Initializing = 1,   // 初始化中
    Ready = 2,          // 就绪
    Acquiring = 3,      // 采集中
    Correcting = 4,     // 校正中
    Error = 5           // 错误
}
```

### 9.2 状态监控

```csharp
// 监控探测器状态变化 | Monitor detector status changes
private void MonitorStatus()
{
    DetectorStatus currentStatus = _detectorService.Status;
    
    switch (currentStatus)
    {
        case DetectorStatus.Uninitialized:
            StatusMessage = "未初始化 | Uninitialized";
            break;
        case DetectorStatus.Initializing:
            StatusMessage = "初始化中... | Initializing...";
            break;
        case DetectorStatus.Ready:
            StatusMessage = "就绪 | Ready";
            break;
        case DetectorStatus.Acquiring:
            StatusMessage = "采集中... | Acquiring...";
            break;
        case DetectorStatus.Correcting:
            StatusMessage = "校正中... | Correcting...";
            break;
        case DetectorStatus.Error:
            StatusMessage = "错误 | Error";
            // 获取错误信息 | Get error information
            DetectorResult error = _detectorService.GetLastError();
            _logger.Error(null, $"探测器错误: {error.ErrorMessage}");
            break;
    }
}
```

---

## 10. 异常处理 | Exception Handling

### 10.1 DetectorResult 结果处理

所有操作返回 `DetectorResult` 对象：

```csharp
DetectorResult result = await _detectorService.InitializeAsync();

if (result.IsSuccess)
{
    // 操作成功 | Operation successful
    _logger.Info("操作成功");
}
else
{
    // 操作失败 | Operation failed
    string error = result.ErrorMessage;
    int errorCode = result.ErrorCode;
    Exception exception = result.Exception;
    
    _logger.Error(exception, $"操作失败: {error}, 错误码: {errorCode}");
}
```

### 10.2 异常捕获

```csharp
try
{
    DetectorResult result = await _detectorService.AcquireSingleFrameAsync();
    // 处理结果 | Process result
}
catch (TimeoutException ex)
{
    // 超时异常 | Timeout exception
    _logger.Error(ex, "操作超时");
    MessageBox.Show("操作超时，请检查探测器连接", "超时", 
        MessageBoxButton.OK, MessageBoxImage.Warning);
}
catch (InvalidOperationException ex)
{
    // 无效操作异常 | Invalid operation exception
    _logger.Error(ex, "无效操作");
    MessageBox.Show($"无效操作: {ex.Message}", "错误", 
        MessageBoxButton.OK, MessageBoxImage.Error);
}
catch (Exception ex)
{
    // 其他异常 | Other exceptions
    _logger.Error(ex, "未知错误");
    MessageBox.Show($"发生错误: {ex.Message}", "错误", 
        MessageBoxButton.OK, MessageBoxImage.Error);
}
```

---

## 11. 日志记录 | Logging

模块使用 Serilog 进行结构化日志记录：

### 11.1 日志级别

- **Debug**: 详细的调试信息（帧采集、状态变化等）
- **Info**: 一般信息（初始化成功、采集开始等）
- **Warn**: 警告信息（状态异常、参数警告等）
- **Error**: 错误信息（操作失败、通讯异常等）
- **Fatal**: 致命错误（系统崩溃等）

### 11.2 日志示例

```csharp
// 信息日志 | Info log
_logger.Info("探测器初始化成功 | Detector initialized successfully");

// 警告日志 | Warning log
_logger.Warn("探测器未就绪 | Detector not ready");

// 错误日志 | Error log
_logger.Error(ex, $"操作失败: {ex.Message} | Operation failed: {ex.Message}");

// 调试日志 | Debug log
_logger.Debug($"采集帧 {frameNumber} | Acquired frame {frameNumber}");
```

---

## 12. 性能优化建议 | Performance Optimization Suggestions

### 12.1 图像处理

避免在 UI 线程处理大图像：

```csharp
// 推荐：在后台线程处理图像 | Recommended: Process images in background thread
await Task.Run(() =>
{
    // 图像处理逻辑 | Image processing logic
    ProcessImage(imageData);
});
```

### 12.2 异步操作

所有 I/O 操作使用异步方法：

```csharp
// 正确：异步操作 | Correct: Async operation
await _detectorService.AcquireSingleFrameAsync();

// 错误：同步阻塞 | Wrong: Synchronous blocking
_detectorService.AcquireSingleFrameAsync().Wait(); // 不要这样做！
```

### 12.3 事件订阅

及时取消不再需要的事件订阅：

```csharp
// 保存订阅令牌 | Save subscription token
private SubscriptionToken _imageCapturedToken;

// 订阅事件 | Subscribe to event
_imageCapturedToken = _eventAggregator.GetEvent<ImageCapturedEvent>()
    .Subscribe(OnImageCaptured, ThreadOption.UIThread);

// 取消订阅 | Unsubscribe
_eventAggregator.GetEvent<ImageCapturedEvent>()
    .Unsubscribe(_imageCapturedToken);
```

---

## 13. 故障排查 | Troubleshooting

### 13.1 初始化失败

**问题**: 探测器初始化失败

**可能原因**:
- 探测器 IP 地址或端口配置错误
- 探测器未启动或网络不通
- 探测器驱动未正确安装
- 配置文件参数错误

**解决方案**:
1. 检查 `App.config` 中的探测器连接参数
2. 使用 `ping` 命令测试探测器网络连接
3. 确认探测器驱动和 SDK 已安装
4. 查看日志文件获取详细错误信息

### 13.2 采集失败

**问题**: 无法采集图像

**可能原因**:
- 探测器未初始化
- 探测器处于错误状态
- 校正未完成
- 网络通讯异常

**解决方案**:
1. 确认已调用 `InitializeAsync()` 并成功
2. 检查探测器状态是否为 `Ready`
3. 执行自动校正 `AutoCorrectionAsync()`
4. 检查网络连接和通讯日志

### 13.3 校正失败

**问题**: 校正操作失败

**可能原因**:
- 探测器未就绪
- 射线源未开启（增益校正需要）
- 采集帧数不足
- 环境光干扰

**解决方案**:
1. 确认探测器状态为 `Ready`
2. 增益校正前确保射线源已开启
3. 增加采集帧数（建议 10 帧以上）
4. 检查暗场环境，避免光线干扰

### 13.4 通讯超时

**问题**: 操作超时

**可能原因**:
- 网络延迟过高
- 探测器响应慢
- 超时配置过短

**解决方案**:
1. 检查网络连接质量
2. 增加配置文件中的超时时间
3. 检查探测器负载情况

---

## 14. 注意事项 | Notes

1. **线程安全**: `IDetectorService` 是单例，多个 ViewModel 共享同一个实例
2. **异步操作**: 所有操作都是异步的，避免阻塞 UI 线程
3. **状态检查**: 操作前检查探测器状态，确保处于正确状态
4. **资源释放**: 应用退出时探测器会自动停止采集并释放资源
5. **事件订阅**: 记得在 ViewModel 销毁时取消事件订阅
6. **校正顺序**: 建议按照暗场→增益→坏像素的顺序进行校正
7. **日志记录**: 所有关键操作都有详细的日志记录
8. **错误处理**: 始终检查 `DetectorResult.IsSuccess` 并处理错误

---

## 15. 文档索引 | Documentation Index

- **[GUIDENCE.md](./GUIDENCE.md)** - 本文档，详细使用指南
- **[README.md](./README.md)** - 项目概述和快速参考
- **[App.config.example](./App.config.example)** - 配置文件示例

---

## 16. 技术支持 | Technical Support

如有问题或建议，请联系项目维护团队。

---

**最后更新 | Last Updated**: 2026-03-11
