优化了代码

This commit is contained in:
2025-07-15 18:28:17 +08:00
parent cd4b249bf9
commit 656bb924bc
2 changed files with 167 additions and 131 deletions

View File

@@ -1,18 +1,11 @@
using System; using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using MQTTnet; using MQTTnet;
using MQTTnet.Client; using MQTTnet.Client;
using MQTTnet.Client.Connecting; using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting; using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options; using MQTTnet.Client.Options;
using PMSWPF.Models;
using PMSWPF.Services;
using PMSWPF.Helper; using PMSWPF.Helper;
using PMSWPF.Enums; using PMSWPF.Models;
namespace PMSWPF.Services namespace PMSWPF.Services
{ {
@@ -69,7 +62,7 @@ namespace PMSWPF.Services
_serviceMainThread.Start(); _serviceMainThread.Start();
} }
private void Execute() private async void Execute()
{ {
while (!_stopEvent.WaitOne(0)) while (!_stopEvent.WaitOne(0))
{ {
@@ -81,19 +74,31 @@ namespace PMSWPF.Services
_reloadEvent.WaitOne(); _reloadEvent.WaitOne();
try
{
// 初始加载MQTT配置和变量数据。 // 初始加载MQTT配置和变量数据。
LoadMqttConfigurations(); var isLoaded = LoadMqttConfigurations();
ConnectMqttList(); if (isLoaded)
{
await ConnectMqttList();
}
}
catch (Exception e)
{
NotificationHelper.ShowError($"Mqt后台服务主程序在加载变量和连接服务器过程中出现了错误{e.Message} ", e);
}
finally
{
_reloadEvent.Reset(); _reloadEvent.Reset();
} }
} }
}
/// <summary> /// <summary>
/// 停止MQTT后台服务。 /// 停止MQTT后台服务。
/// </summary> /// </summary>
public void StopService() public async Task StopService()
{ {
NlogHelper.Info("Mqtt后台服务开始停止...."); // 记录服务停止信息 NlogHelper.Info("Mqtt后台服务开始停止...."); // 记录服务停止信息
@@ -101,7 +106,7 @@ namespace PMSWPF.Services
// 取消订阅事件。 // 取消订阅事件。
_dataServices.OnMqttListChanged -= HandleMqttListChanged; _dataServices.OnMqttListChanged -= HandleMqttListChanged;
DisconnecetAll(); await DisconnecetAll();
// 清空所有字典。 // 清空所有字典。
_mqttClients.Clear(); _mqttClients.Clear();
@@ -110,19 +115,24 @@ namespace PMSWPF.Services
NlogHelper.Info("Mqtt后台服务已停止。"); // 记录服务停止信息 NlogHelper.Info("Mqtt后台服务已停止。"); // 记录服务停止信息
} }
private void DisconnecetAll() private async Task DisconnecetAll()
{ {
// 断开所有已连接的MQTT客户端。 // 断开所有已连接的MQTT客户端。
foreach (var mqttId in _mqttClients.Keys.ToList()) foreach (var mqttId in _mqttClients.Keys.ToList())
{
try
{ {
var client = _mqttClients[mqttId]; var client = _mqttClients[mqttId];
var mqtt = _mqttConfigDic[mqttId]; var mqtt = _mqttConfigDic[mqttId];
mqtt.IsConnected = false; mqtt.IsConnected = false;
if (client.IsConnected) if (client.IsConnected)
{ {
client.DisconnectAsync() await client.DisconnectAsync();
.GetAwaiter() }
.GetResult(); }
catch (Exception e)
{
NlogHelper.Error($"MqttID:{mqttId},断开连接的过程中发生了错误:{e.Message}",e);
} }
} }
} }
@@ -132,7 +142,9 @@ namespace PMSWPF.Services
/// 加载并连接MQTT配置。 /// 加载并连接MQTT配置。
/// </summary> /// </summary>
/// <returns>表示异步操作的任务。</returns> /// <returns>表示异步操作的任务。</returns>
private void LoadMqttConfigurations() private bool LoadMqttConfigurations()
{
try
{ {
NlogHelper.Info("开始加载Mqtt配置文件..."); NlogHelper.Info("开始加载Mqtt配置文件...");
_mqttConfigDic.Clear(); _mqttConfigDic.Clear();
@@ -147,6 +159,13 @@ namespace PMSWPF.Services
} }
NlogHelper.Info($"Mqtt配置文件加载成功开启的Mqtt客户端{_mqttConfigList.Count}个。"); NlogHelper.Info($"Mqtt配置文件加载成功开启的Mqtt客户端{_mqttConfigList.Count}个。");
return true;
}
catch (Exception e)
{
NotificationHelper.ShowError($"Mqtt后台服务在加载变量的过程中发生了错误:{e.Message}");
return false;
}
} }
private async void OnMqttIsActiveChangedHandler(Mqtt mqtt) private async void OnMqttIsActiveChangedHandler(Mqtt mqtt)
@@ -175,14 +194,12 @@ namespace PMSWPF.Services
_mqttClients.Remove(mqtt.Id); _mqttClients.Remove(mqtt.Id);
NlogHelper.Info($"{mqtt.Name}的客户端,与服务器断开连接."); NlogHelper.Info($"{mqtt.Name}的客户端,与服务器断开连接.");
} }
} }
catch (Exception e) catch (Exception e)
{ {
NotificationHelper.ShowError($"{mqtt.Name}客户端,开启或关闭的过程中发生了错误:{e.Message}", e); NotificationHelper.ShowError($"{mqtt.Name}客户端,开启或关闭的过程中发生了错误:{e.Message}", e);
} }
} }
/// <summary> /// <summary>
@@ -247,7 +264,7 @@ namespace PMSWPF.Services
private static void HandleMessageReceived(MqttApplicationMessageReceivedEventArgs e, Mqtt mqtt) private static void HandleMessageReceived(MqttApplicationMessageReceivedEventArgs e, Mqtt mqtt)
{ {
var topic = e.ApplicationMessage.Topic; var topic = e.ApplicationMessage.Topic;
var payload = System.Text.Encoding.UTF8.GetString(e.ApplicationMessage.Payload); var payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
NlogHelper.Info($"MQTT客户端 {mqtt.Name} 收到消息: 主题={topic}, 消息={payload}"); NlogHelper.Info($"MQTT客户端 {mqtt.Name} 收到消息: 主题={topic}, 消息={payload}");
// 在这里添加处理消息的逻辑 // 在这里添加处理消息的逻辑

View File

@@ -1,17 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using S7.Net;
using PMSWPF.Models;
using PMSWPF.Enums; using PMSWPF.Enums;
using PMSWPF.Helper; using PMSWPF.Helper;
using PMSWPF.Models;
using S7.Net;
using S7.Net.Types; using S7.Net.Types;
using SqlSugar;
using DateTime = System.DateTime; using DateTime = System.DateTime;
namespace PMSWPF.Services namespace PMSWPF.Services
@@ -40,6 +31,8 @@ namespace PMSWPF.Services
// S7轮询一遍后的等待时间 // S7轮询一遍后的等待时间
private readonly int S7PollOnceSleepTimeMs = 100; private readonly int S7PollOnceSleepTimeMs = 100;
Dictionary<int, DataItem> _readVariableDic;
// 轮询数据的线程。 // 轮询数据的线程。
private Thread _pollingThread; private Thread _pollingThread;
@@ -62,6 +55,7 @@ namespace PMSWPF.Services
_pollVariableDic = new(); _pollVariableDic = new();
_s7PlcClientDic = new(); _s7PlcClientDic = new();
_variableDic = new(); _variableDic = new();
_readVariableDic = new();
// 订阅设备列表变更事件,以便在设备配置更新时重新加载。 // 订阅设备列表变更事件,以便在设备配置更新时重新加载。
_dataServices.OnDeviceListChanged += HandleDeviceListChanged; _dataServices.OnDeviceListChanged += HandleDeviceListChanged;
} }
@@ -116,6 +110,11 @@ namespace PMSWPF.Services
_reloadEvent.Reset(); _reloadEvent.Reset();
} }
} }
catch (ThreadInterruptedException tie)
{
NlogHelper.Error($"S7后台服务主线程关闭。");
DisconnectAllPlc();
}
catch (Exception e) catch (Exception e)
{ {
NlogHelper.Error($"S7后台服务主线程运行中发生了错误:{e.Message}",e); NlogHelper.Error($"S7后台服务主线程运行中发生了错误:{e.Message}",e);
@@ -134,7 +133,6 @@ namespace PMSWPF.Services
try try
{ {
// Stopwatch sw = Stopwatch.StartNew(); // Stopwatch sw = Stopwatch.StartNew();
int varCount = 0;
// 遍历并读取每个S7变量。 // 遍历并读取每个S7变量。
foreach (var deviceId in _pollVariableDic.Keys.ToList()) foreach (var deviceId in _pollVariableDic.Keys.ToList())
{ {
@@ -163,7 +161,7 @@ namespace PMSWPF.Services
continue; continue;
} }
Dictionary<int, DataItem> readVarDic = new Dictionary<int, DataItem>();
foreach (var variable in variableList) foreach (var variable in variableList)
{ {
@@ -178,38 +176,7 @@ namespace PMSWPF.Services
if ((DateTime.Now - variable.UpdateTime) < interval) if ((DateTime.Now - variable.UpdateTime) < interval)
continue; // 未到轮询时间,跳过。 continue; // 未到轮询时间,跳过。
try ReadVariableData(variable, plcClient, device);
{
readVarDic.Add(variable.Id, DataItem.FromAddress(variable.S7Address));
varCount++;
if (readVarDic.Count == S7PollOnceReadMultipleVars)
{
// 批量读取
plcClient.ReadMultipleVars(readVarDic.Values.ToList());
// 批量读取后还原结果
foreach (var varId in readVarDic.Keys.ToList())
{
DataItem dataItem = readVarDic[varId];
if (!_variableDic.TryGetValue(varId, out var variableData))
{
NlogHelper.Warn($"S7后台服务批量读取变量后还原值在_variableDic中找不到ID为{varId}的变量");
continue;
}
// 更新变量的原始数据值和显示值。
variableData.DataValue = dataItem.Value.ToString();
variableData.UpdateTime = DateTime.Now;
Console.WriteLine($"S7轮询变量:{variableData.Name},值:{variableData.DataValue}");
}
readVarDic.Clear();
}
}
catch (Exception ex)
{
NlogHelper.Warn($"从设备 {device.Name} 读取变量 {variable.Name} 失败:{ex.Message}");
}
} }
} }
@@ -225,6 +192,11 @@ namespace PMSWPF.Services
NlogHelper.Info("S7后台服务轮询变量结束。"); NlogHelper.Info("S7后台服务轮询变量结束。");
} }
catch (ThreadInterruptedException tie)
{
NlogHelper.Error($"S7后台服务轮询变量线程关闭。");
DisconnectAllPlc();
}
catch (Exception e) catch (Exception e)
{ {
NlogHelper.Error($"S7后台服务轮询变量线程运行中发生了错误:{e.Message}",e); NlogHelper.Error($"S7后台服务轮询变量线程运行中发生了错误:{e.Message}",e);
@@ -232,6 +204,48 @@ namespace PMSWPF.Services
} }
} }
/// <summary>
/// 读取变量数据
/// </summary>
/// <param name="variable"></param>
/// <param name="plcClient"></param>
/// <param name="device"></param>
private void ReadVariableData(VariableData variable,
Plc plcClient, Device device)
{
try
{
_readVariableDic.Add(variable.Id, DataItem.FromAddress(variable.S7Address));
if (_readVariableDic.Count == S7PollOnceReadMultipleVars)
{
// 批量读取
plcClient.ReadMultipleVars(_readVariableDic.Values.ToList());
// 批量读取后还原结果
foreach (var varId in _readVariableDic.Keys.ToList())
{
DataItem dataItem = _readVariableDic[varId];
if (!_variableDic.TryGetValue(varId, out var variableData))
{
NlogHelper.Warn($"S7后台服务批量读取变量后还原值在_variableDic中找不到ID为{varId}的变量");
continue;
}
// 更新变量的原始数据值和显示值。
variableData.DataValue = dataItem.Value.ToString();
variableData.UpdateTime = DateTime.Now;
Console.WriteLine($"S7轮询变量:{variableData.Name},值:{variableData.DataValue}");
}
_readVariableDic.Clear();
}
}
catch (Exception ex)
{
NlogHelper.Warn($"从设备 {device.Name} 读取变量 {variable.Name} 失败:{ex.Message}");
}
}
private void ConnectS7Service() private void ConnectS7Service()
{ {
try try
@@ -249,14 +263,7 @@ namespace PMSWPF.Services
var plcClient = new Plc(device.CpuType, device.Ip, (short)device.Prot, device.Rack, device.Slot); var plcClient = new Plc(device.CpuType, device.Ip, (short)device.Prot, device.Rack, device.Slot);
plcClient.Open(); // 尝试打开连接。 plcClient.Open(); // 尝试打开连接。
// 将新创建的客户端添加到字典。 // 将新创建的客户端添加到字典。
if (_s7PlcClientDic.ContainsKey(device.Ip))
{
_s7PlcClientDic[device.Ip] = plcClient; _s7PlcClientDic[device.Ip] = plcClient;
}
else
{
_s7PlcClientDic.Add(device.Ip, plcClient);
}
NotificationHelper.ShowSuccess($"已连接到S7 PLC: {device.Name} ({device.Ip})"); NotificationHelper.ShowSuccess($"已连接到S7 PLC: {device.Name} ({device.Ip})");
} }
@@ -267,6 +274,9 @@ namespace PMSWPF.Services
} }
} }
/// <summary>
/// 加载变量
/// </summary>
private void LoadVariables() private void LoadVariables()
{ {
try try
@@ -291,16 +301,8 @@ namespace PMSWPF.Services
.ToList(); .ToList();
// 将变量存储到字典中方便以后通过ID快速查找 // 将变量存储到字典中方便以后通过ID快速查找
foreach (var s7Variable in s7Variables) foreach (var s7Variable in s7Variables)
{
if (_variableDic.ContainsKey(s7Variable.Id))
{
_variableDic[s7Variable.Id] = s7Variable; _variableDic[s7Variable.Id] = s7Variable;
}
else
{
_variableDic.Add(s7Variable.Id, s7Variable);
}
}
varCount += s7Variables.Count(); varCount += s7Variables.Count();
_pollVariableDic.Add(device.Id, s7Variables); _pollVariableDic.Add(device.Id, s7Variables);
@@ -319,6 +321,8 @@ namespace PMSWPF.Services
/// 停止S7后台服务。 /// 停止S7后台服务。
/// </summary> /// </summary>
public void StopService() public void StopService()
{
try
{ {
NlogHelper.Info("S7后台服务正在关闭...."); NlogHelper.Info("S7后台服务正在关闭....");
_stopEvent.Set(); _stopEvent.Set();
@@ -341,13 +345,23 @@ namespace PMSWPF.Services
_pollVariableDic.Clear(); _pollVariableDic.Clear();
NlogHelper.Info("S7后台服务已关闭"); NlogHelper.Info("S7后台服务已关闭");
} }
catch (Exception e)
{
NlogHelper.Error($"S7后台服务关闭时发生了错误{e.Message}",e);
}
}
/// <summary>
/// 关闭所有PLC的连接
/// </summary>
private void DisconnectAllPlc() private void DisconnectAllPlc()
{ {
if (_s7PlcClientDic==null || _s7PlcClientDic.Count == 0) if (_s7PlcClientDic==null || _s7PlcClientDic.Count == 0)
return; return;
// 关闭所有活跃的PLC连接。 // 关闭所有活跃的PLC连接。
foreach (var plcClient in _s7PlcClientDic.Values.ToList()) foreach (var plcClient in _s7PlcClientDic.Values.ToList())
{
try
{ {
if (plcClient.IsConnected) if (plcClient.IsConnected)
{ {
@@ -355,6 +369,11 @@ namespace PMSWPF.Services
NlogHelper.Info($"关闭S7连接: {plcClient.IP}"); NlogHelper.Info($"关闭S7连接: {plcClient.IP}");
} }
} }
catch (Exception e)
{
NlogHelper.Error($"S7后台服务关闭{plcClient.IP},后台连接时发生错误:{e.Message}",e);
}
}
} }
} }
} }