Files
Ayay/SHH.CameraService/CameraEngineWorker.cs

113 lines
4.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.Extensions.Hosting;
using SHH.CameraSdk;
namespace SHH.CameraService;
/// <summary>
/// 相机服务核心引擎工作者(后台长驻服务)
/// <para>核心职责:</para>
/// <para>1. 管理 CameraManager 全生命周期(启动、配置、释放)</para>
/// <para>2. 初始化网络哨兵ConnectivitySentinel监控设备网络连通性</para>
/// <para>3. 无配置时自动添加默认测试设备,降低调试门槛</para>
/// <para>设计说明:</para>
/// <para>- 基于 BackgroundService运行在独立后台线程不阻塞 Web 主线程</para>
/// <para>- 与 CameraManager 强绑定,是所有相机设备的统一入口</para>
/// <para>- 包含容错机制,添加设备失败不影响整体服务启动</para>
public class CameraEngineWorker : BackgroundService
{
#region --- ---
/// <summary>
/// 相机管理器实例(核心业务对象)
/// 功能:管理所有相机设备的生命周期、状态监控、配置更新
/// </summary>
private readonly CameraManager _manager;
/// <summary>
/// 网络连通性哨兵实例
/// 功能:周期性 Ping 设备、检测网络状态、触发断线重连
/// </summary>
private readonly ConnectivitySentinel _sentinel;
#endregion
#region --- ---
/// <summary>
/// 初始化相机引擎工作者实例
/// </summary>
/// <param name="manager">相机管理器(通过 DI 注入,已关联存储服务)</param>
/// <param name="sentinel">网络哨兵(通过 DI 注入,已预设监控周期)</param>
public CameraEngineWorker(CameraManager manager, ConnectivitySentinel sentinel)
{
_manager = manager ?? throw new ArgumentNullException(
nameof(manager), "相机管理器实例不能为空,核心引擎启动失败");
_sentinel = sentinel ?? throw new ArgumentNullException(
nameof(sentinel), "网络哨兵实例不能为空,设备监控功能失效");
}
#endregion
#region --- BackgroundService ---
/// <summary>
/// 启动引擎:初始化相机管理器并加载业务配置
/// <para>执行流程:</para>
/// <para>1. 启动 CameraManager加载本地配置文件中的设备信息</para>
/// <para>2. 加载默认业务逻辑(无设备时添加测试设备)</para>
/// <para>注意:网络哨兵的启动逻辑已内置在其构造函数中,此处无需额外调用</para>
/// </summary>
/// <param name="stoppingToken">服务停止令牌(响应应用关闭/重启信号)</param>
/// <returns>异步任务(引擎启动完成后结束)</returns>
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
Console.WriteLine("[Engine] 核心引擎启动中...");
Console.WriteLine("[Engine] 启动相机管理器(加载设备配置)");
try
{
// 启动相机管理器:加载 App_Data/Process_X 目录下的设备配置文件
await _manager.StartAsync();
Console.WriteLine("[Engine] 相机管理器启动成功,已加载配置文件中的设备");
}
catch (Exception ex)
{
Console.WriteLine($"[Engine] 相机管理器启动失败:{ex.Message}");
Console.WriteLine("[Engine] 警告:核心引擎将继续运行,但无法管理任何相机设备");
return;
}
Console.WriteLine("[Engine] 核心引擎启动完成,进入运行状态");
Console.WriteLine("[Engine] 提示:可通过 API 接口添加/编辑/删除设备,实时生效");
}
/// <summary>
/// 停止引擎:优雅释放资源
/// <para>执行流程:</para>
/// <para>1. 调用 CameraManager.DisposeAsync(),释放所有设备连接、句柄、线程资源</para>
/// <para>2. 调用基类 StopAsync(),标记服务停止状态</para>
/// <para>注意:必须先释放 CameraManager避免设备连接泄露</para>
/// </summary>
/// <param name="cancellationToken">取消令牌(用于强制终止释放流程)</param>
/// <returns>异步任务(资源释放完成后结束)</returns>
public override async Task StopAsync(CancellationToken cancellationToken)
{
Console.WriteLine("[Engine] 核心引擎正在停止...");
try
{
// 释放相机管理器:停止所有设备取流、注销登录、释放非托管资源
await _manager.DisposeAsync();
Console.WriteLine("[Engine] 相机管理器资源已释放");
}
catch (Exception ex)
{
Console.WriteLine($"[Engine] 资源释放异常:{ex.Message}");
}
// 调用基类方法,完成服务停止
await base.StopAsync(cancellationToken);
Console.WriteLine("[Engine] 核心引擎已停止");
}
#endregion
}