将开关后台服务改为实时响应

This commit is contained in:
2025-07-07 21:24:45 +08:00
parent 308c50fe15
commit 8b7658a4a3
5 changed files with 55 additions and 34 deletions

View File

@@ -66,10 +66,25 @@ public partial class App : Application
MainWindow = Host.Services.GetRequiredService<MainView>();
MainWindow.Show();
// 根据配置启动服务
var connectionSettings = PMSWPF.Config.ConnectionSettings.Load();
if (connectionSettings.EnableS7Service)
{
Host.Services.GetRequiredService<S7BackgroundService>().StartService();
}
if (connectionSettings.EnableMqttService)
{
Host.Services.GetRequiredService<MqttBackgroundService>().StartService();
}
}
protected override async void OnExit(ExitEventArgs e)
{
// 停止服务
Host.Services.GetRequiredService<S7BackgroundService>().StopService();
Host.Services.GetRequiredService<MqttBackgroundService>().StopService();
await Host.StopAsync();
Host.Dispose();
LogManager.Shutdown();
@@ -82,14 +97,8 @@ public partial class App : Application
services.AddSingleton<NavgatorServices>();
services.AddSingleton<IDialogService, DialogService>();
services.AddSingleton<GrowlNotificationService>();
if (ConnectionSettings.Load().EnableS7Service)
{
services.AddHostedService<S7BackgroundService>(); // Register as HostedService
}
if (ConnectionSettings.Load().EnableMqttService)
{
services.AddHostedService<MqttBackgroundService>();
}
services.AddSingleton<S7BackgroundService>();
services.AddSingleton<MqttBackgroundService>();
services.AddSingleton<MainViewModel>();
services.AddSingleton<HomeViewModel>();
services.AddSingleton<DevicesViewModel>();

View File

@@ -17,7 +17,7 @@ namespace PMSWPF.Services
/// <summary>
/// MQTT后台服务继承自BackgroundService用于在后台管理MQTT连接和数据发布。
/// </summary>
public class MqttBackgroundService : BackgroundService
public class MqttBackgroundService
{
// 数据服务实例用于访问和操作应用程序数据如MQTT配置和变量数据。
private readonly DataServices _dataServices;
@@ -43,11 +43,9 @@ namespace PMSWPF.Services
}
/// <summary>
/// 后台服务的执行方法,当服务启动时调用
/// 启动MQTT后台服务。
/// </summary>
/// <param name="stoppingToken">用于取消操作的CancellationToken。</param>
/// <returns>表示异步操作的任务。</returns>
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
public async void StartService()
{
NlogHelper.Info("MqttBackgroundService started."); // 记录服务启动信息
@@ -63,15 +61,13 @@ namespace PMSWPF.Services
_timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5)); // 每5秒轮询一次
// 使服务保持运行,直到收到停止请求。
await Task.Delay(Timeout.Infinite, stoppingToken);
// await Task.Delay(Timeout.Infinite, stoppingToken);
}
/// <summary>
/// 后台服务的停止方法,当服务停止时调用
/// 停止MQTT后台服务。
/// </summary>
/// <param name="stoppingToken">用于取消操作的CancellationToken。</param>
/// <returns>表示异步操作的任务。</returns>
public override async Task StopAsync(CancellationToken stoppingToken)
public async void StopService()
{
NlogHelper.Info("MqttBackgroundService stopping."); // 记录服务停止信息
@@ -95,7 +91,7 @@ namespace PMSWPF.Services
_mqttConfigurations.Clear();
_mqttVariableData.Clear();
await base.StopAsync(stoppingToken);
}
/// <summary>

View File

@@ -16,7 +16,7 @@ namespace PMSWPF.Services
/// <summary>
/// S7后台服务继承自BackgroundService用于在后台周期性地轮询S7 PLC设备数据。
/// </summary>
public class S7BackgroundService : BackgroundService
public class S7BackgroundService
{
// 数据服务实例,用于访问和操作应用程序数据,如设备配置。
private readonly DataServices _dataServices;
@@ -91,15 +91,13 @@ namespace PMSWPF.Services
}
/// <summary>
/// 后台服务的执行方法,当服务启动时调用
/// 启动S7后台服务。
/// </summary>
/// <param name="stoppingToken">用于取消操作的CancellationToken。</param>
/// <returns>表示异步操作的任务。</returns>
protected override Task ExecuteAsync(CancellationToken stoppingToken)
public void StartService()
{
NlogHelper.Info("S7后台服务正在启动。");
// 创建一个CancellationTokenSource用于控制轮询线程的取消。
_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
_cancellationTokenSource = new CancellationTokenSource();
// 创建并启动轮询线程。
_pollingThread = new Thread(() => PollingLoop(_cancellationTokenSource.Token))
@@ -107,8 +105,6 @@ namespace PMSWPF.Services
IsBackground = true // 设置为后台线程,随主程序退出而退出
};
_pollingThread.Start();
return Task.CompletedTask;
}
/// <summary>
@@ -307,11 +303,9 @@ namespace PMSWPF.Services
}
/// <summary>
/// 后台服务的停止方法,当服务停止时调用
/// 停止S7后台服务。
/// </summary>
/// <param name="stoppingToken">用于取消操作的CancellationToken。</param>
/// <returns>表示异步操作的任务。</returns>
public override async Task StopAsync(CancellationToken stoppingToken)
public void StopService()
{
NlogHelper.Info("S7 Background Service is stopping.");
@@ -332,7 +326,7 @@ namespace PMSWPF.Services
_s7PlcClients.Clear(); // 清空PLC客户端字典。
await base.StopAsync(stoppingToken);
}
}
}

View File

@@ -7,17 +7,22 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using PMSWPF.Services;
namespace PMSWPF.ViewModels;
public partial class SettingViewModel : ViewModelBase
{
private ConnectionSettings _connectionSettings;
private readonly S7BackgroundService _s7BackgroundService;
private readonly MqttBackgroundService _mqttBackgroundService;
public SettingViewModel()
public SettingViewModel(S7BackgroundService s7BackgroundService, MqttBackgroundService mqttBackgroundService)
{
_connectionSettings = ConnectionSettings.Load();
AvailableDbTypes = Enum.GetNames(typeof(SqlSugar.DbType)).ToList();
_s7BackgroundService = s7BackgroundService;
_mqttBackgroundService = mqttBackgroundService;
}
public List<string> AvailableDbTypes { get; set; }
@@ -116,6 +121,14 @@ public partial class SettingViewModel : ViewModelBase
_connectionSettings.EnableS7Service = value;
OnPropertyChanged();
_connectionSettings.Save();
if (value)
{
_s7BackgroundService.StartService();
}
else
{
_s7BackgroundService.StopService();
}
}
}
}
@@ -130,6 +143,14 @@ public partial class SettingViewModel : ViewModelBase
_connectionSettings.EnableMqttService = value;
OnPropertyChanged();
_connectionSettings.Save();
if (value)
{
_mqttBackgroundService.StartService();
}
else
{
_mqttBackgroundService.StopService();
}
}
}
}

View File

@@ -1,5 +1,6 @@
using PMSWPF.ViewModels;
using System.Windows.Controls;
using Microsoft.Extensions.DependencyInjection;
namespace PMSWPF.Views;
@@ -8,6 +9,6 @@ public partial class SettingView : UserControl
public SettingView()
{
InitializeComponent();
DataContext = new SettingViewModel();
DataContext = App.Current.Services.GetRequiredService<SettingViewModel>();
}
}