完成S7变量启用和停用更新

This commit is contained in:
2025-09-16 14:42:23 +08:00
parent 3102938f92
commit 74fde6bd8b
59 changed files with 226 additions and 454 deletions

View File

@@ -0,0 +1,157 @@
using DMS.Application.DTOs;
using DMS.Application.Events;
using DMS.Application.Interfaces;
using DMS.Core.Enums;
using DMS.Infrastructure.Interfaces.Services;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace DMS.Infrastructure.Services.OpcUa
{
/// <summary>
/// 优化后的OPC UA后台服务
/// </summary>
public class OptimizedOpcUaBackgroundService : BackgroundService
{
private readonly IAppDataCenterService _appDataCenterService;
private readonly IAppDataStorageService _appDataStorageService;
private readonly IEventService _eventService;
private readonly IOpcUaServiceManager _opcUaServiceManager;
private readonly ILogger<OptimizedOpcUaBackgroundService> _logger;
private readonly SemaphoreSlim _reloadSemaphore = new SemaphoreSlim(0);
public OptimizedOpcUaBackgroundService(
IAppDataCenterService appDataCenterService,
IAppDataStorageService appDataStorageService,
IOpcUaServiceManager opcUaServiceManager,
ILogger<OptimizedOpcUaBackgroundService> logger)
{
_appDataCenterService = appDataCenterService ?? throw new ArgumentNullException(nameof(appDataCenterService));
_appDataStorageService = appDataStorageService;
_opcUaServiceManager = opcUaServiceManager ?? throw new ArgumentNullException(nameof(opcUaServiceManager));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_appDataCenterService.DataLoaderService.OnLoadDataCompleted += OnLoadDataCompleted;
}
private void OnLoadDataCompleted(object sender, DataLoadCompletedEventArgs e)
{
_logger.LogInformation("收到数据加载完成通知触发OPC UA服务重新加载");
_reloadSemaphore.Release();
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("优化后的OPC UA后台服务正在启动...");
try
{
// 初始化服务管理器
await _opcUaServiceManager.InitializeAsync(stoppingToken);
while (!stoppingToken.IsCancellationRequested)
{
await _reloadSemaphore.WaitAsync(stoppingToken);
if (stoppingToken.IsCancellationRequested)
break;
if (_appDataStorageService.Devices.IsEmpty)
{
_logger.LogInformation("没有可用的OPC UA设备等待设备列表更新...");
continue;
}
await LoadAndConnectDevicesAsync(stoppingToken);
}
}
catch (OperationCanceledException)
{
_logger.LogInformation("OPC UA后台服务已收到停止请求");
}
catch (Exception ex)
{
_logger.LogError(ex, "OPC UA后台服务运行时发生未处理的异常: {ErrorMessage}", ex.Message);
}
finally
{
_logger.LogInformation("正在清理OPC UA后台服务资源...");
// 服务管理器会在Dispose时自动清理资源
}
_logger.LogInformation("优化后的OPC UA后台服务已停止");
}
/// <summary>
/// 加载并连接设备
/// </summary>
private async Task LoadAndConnectDevicesAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("开始加载和连接OPC UA设备...");
try
{
// 获取所有活动的OPC UA设备
var opcUaDevices = _appDataStorageService.Devices.Values
.Where(d => d.Protocol == ProtocolType.OpcUa )
.ToList();
_logger.LogInformation("找到 {DeviceCount} 个OPC UA设备", opcUaDevices.Count);
if (opcUaDevices.Count == 0)
return;
// 添加设备到监控列表
foreach (var device in opcUaDevices)
{
_opcUaServiceManager.AddDevice(device);
// 获取设备变量
var variables = device.VariableTables?
.SelectMany(vt => vt.Variables)
.Where(v => v.IsActive && v.Protocol == ProtocolType.OpcUa)
.ToList() ?? new List<VariableDto>();
_opcUaServiceManager.UpdateVariables(device.Id, variables);
}
// 批量连接设备
var deviceIds = opcUaDevices.Select(d => d.Id).ToList();
await _opcUaServiceManager.ConnectDevicesAsync(deviceIds, stoppingToken);
_logger.LogInformation("OPC UA设备加载和连接完成");
}
catch (Exception ex)
{
_logger.LogError(ex, "加载和连接OPC UA设备时发生错误: {ErrorMessage}", ex.Message);
}
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("正在停止OPC UA后台服务...");
// 释放信号量以确保ExecuteAsync可以退出
_reloadSemaphore.Release();
await base.StopAsync(cancellationToken);
_logger.LogInformation("OPC UA后台服务停止完成");
}
public override void Dispose()
{
_logger.LogInformation("正在释放OPC UA后台服务资源...");
_appDataCenterService.DataLoaderService.OnLoadDataCompleted -= OnLoadDataCompleted;
_reloadSemaphore?.Dispose();
base.Dispose();
_logger.LogInformation("OPC UA后台服务资源已释放");
}
}
}