This commit is contained in:
12
App.xaml.cs
12
App.xaml.cs
@@ -11,7 +11,7 @@ namespace MembranePoreTester
|
||||
public static IPlcService PlcService { get; private set; }
|
||||
public static PlcConfiguration PlcConfig { get; private set; }
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
protected async override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
|
||||
@@ -29,6 +29,16 @@ namespace MembranePoreTester
|
||||
throw new InvalidOperationException("PLC settings missing in appsettings.json");
|
||||
|
||||
PlcService = new ModbusTcpPlcService(PlcConfig);
|
||||
|
||||
var plcService = App.PlcService as ModbusTcpPlcService;
|
||||
try
|
||||
{
|
||||
await plcService.EnsureConnectedAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"PLC 连接失败:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExit(ExitEventArgs e)
|
||||
|
||||
@@ -3,6 +3,8 @@ using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MembranePoreTester.Communication
|
||||
{
|
||||
@@ -17,15 +19,31 @@ namespace MembranePoreTester.Communication
|
||||
_config = config;
|
||||
}
|
||||
|
||||
private async Task EnsureConnectedAsync()
|
||||
public async Task EnsureConnectedAsync(int retryCount = 3)
|
||||
{
|
||||
if (_tcpClient != null && _tcpClient.Connected)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < retryCount; i++)
|
||||
{
|
||||
if (_tcpClient == null || !_tcpClient.Connected)
|
||||
try
|
||||
{
|
||||
_tcpClient?.Close();
|
||||
_tcpClient = new TcpClient();
|
||||
await _tcpClient.ConnectAsync(_config.IpAddress, _config.Port);
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
|
||||
// 现在可以直接使用扩展方法
|
||||
await _tcpClient.ConnectAsync(_config.IpAddress, _config.Port).WithCancellation(cts.Token);
|
||||
_master = ModbusIpMaster.CreateIp(_tcpClient);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) when (i < retryCount - 1)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"连接失败,{500}ms 后重试... {ex.Message}");
|
||||
await Task.Delay(500);
|
||||
}
|
||||
}
|
||||
throw new Exception($"无法连接到 PLC ({_config.IpAddress}:{_config.Port}),请检查网络和 PLC 状态。");
|
||||
}
|
||||
|
||||
// 读取两个连续的保持寄存器,转换为32位浮点数(假设大端模式)
|
||||
public async Task<float> ReadFloatAsync(ushort startAddress)
|
||||
@@ -85,11 +103,12 @@ namespace MembranePoreTester.Communication
|
||||
return result[0];
|
||||
}
|
||||
|
||||
public bool IsConnected => _tcpClient != null && _tcpClient.Connected;
|
||||
|
||||
public async Task<ushort[]> ReadHoldingRegistersAsync(ushort startAddress, ushort count)
|
||||
{
|
||||
await EnsureConnectedAsync();
|
||||
await Task.Delay(100);
|
||||
// await Task.Delay(100);
|
||||
return await _master.ReadHoldingRegistersAsync(_config.SlaveId, startAddress, count);
|
||||
}
|
||||
|
||||
@@ -176,6 +195,22 @@ namespace MembranePoreTester.Communication
|
||||
{
|
||||
_master?.Dispose();
|
||||
_tcpClient?.Close();
|
||||
_tcpClient?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class TaskExtensions
|
||||
{
|
||||
public static async Task WithCancellation(this Task task, CancellationToken cancellationToken)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
|
||||
{
|
||||
if (task != await Task.WhenAny(task, tcs.Task))
|
||||
throw new OperationCanceledException(cancellationToken);
|
||||
}
|
||||
await task;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -599,9 +599,9 @@ namespace MembranePoreTester.ViewModels
|
||||
if (highPressAlarm) newAlarms.Add("高压超限");
|
||||
if (lowPressAlarm) newAlarms.Add("低压超限");
|
||||
|
||||
if (Midnight1) newAlarms.Add("1工位漏夜");
|
||||
if (Midnight2) newAlarms.Add("2工位漏夜");
|
||||
if (Midnight3) newAlarms.Add("3工位漏夜");
|
||||
if (Midnight1) newAlarms.Add("1工位漏液");
|
||||
if (Midnight2) newAlarms.Add("2工位漏液");
|
||||
if (Midnight3) newAlarms.Add("3工位漏液");
|
||||
|
||||
// 更新UI(避免频繁刷新集合导致界面闪烁,直接替换内容)
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace MembranePoreTester.ViewModels
|
||||
|
||||
private async void AutoCollectTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
//if (!IsActive) return;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user