This commit is contained in:
@@ -87,6 +87,10 @@ namespace MembranePoreTester.ViewModels
|
||||
|
||||
public ICommand OpenPressureCalibCommand { get; }
|
||||
|
||||
|
||||
|
||||
private System.Windows.Threading.DispatcherTimer _timer; // 添加定时器字段
|
||||
|
||||
public BubblePointViewModel()
|
||||
{
|
||||
|
||||
@@ -99,15 +103,47 @@ namespace MembranePoreTester.ViewModels
|
||||
SaveCommand = new RelayCommand(SaveToDatabase);
|
||||
ExportCommand = new RelayCommand(ExportToExcel);
|
||||
OpenPressureCalibCommand = new RelayCommand(OpenPressureCalibration);
|
||||
|
||||
|
||||
|
||||
// 启动定时器,每秒读取一次
|
||||
_timer = new System.Windows.Threading.DispatcherTimer();
|
||||
_timer.Interval = TimeSpan.FromSeconds(1);
|
||||
_timer.Tick += async (s, e) => await ReadCurrentPlcAsync();
|
||||
_timer.Start();
|
||||
|
||||
// 立即读取一次
|
||||
Task.Run(async () => await ReadCurrentPlcAsync());
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_timer?.Stop();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
private async Task ReadCurrentPlcAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
float rawPressure = await _plcService.ReadPressureAsync(StationId);
|
||||
Record.BubbleCurrentPressure = rawPressure;
|
||||
OnPropertyChanged(nameof(Record.BubbleCurrentPressure));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"读取PLC失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task ReadPlcAsync()
|
||||
{
|
||||
if (IsDisposed) return; // 改3:添加这行检查
|
||||
try
|
||||
{
|
||||
float rawPressure = await _plcService.ReadPressureAsync(StationId);
|
||||
Record.BubblePointPressure = rawPressure * _plcConfig.PressureFactor;
|
||||
Record.BubblePointPressure = Record.BubbleCurrentPressure;
|
||||
|
||||
OnPropertyChanged(nameof(Record.BubblePointPressure));
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using MembranePoreTester.Communication;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel; // 用于 PropertyChanged
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using static OfficeOpenXml.ExcelErrorValue;
|
||||
|
||||
namespace MembranePoreTester.ViewModels
|
||||
{
|
||||
@@ -117,15 +119,19 @@ namespace MembranePoreTester.ViewModels
|
||||
|
||||
private async Task WritePressureModeAsync(string mode)
|
||||
{
|
||||
ushort val = mode == "高压" ? (ushort)1 : (ushort)0;
|
||||
if (IsDisposed) return;
|
||||
|
||||
ushort val = mode.ToString().Contains("高压") ? (ushort)0 : (ushort)1;
|
||||
try
|
||||
{
|
||||
await _plcService.WriteRegisterAsync(_plcConfig.PressureModeRegister, val);
|
||||
|
||||
await _plcService.WriteSingleRegisterAsync(_plcConfig.PressureModeRegister, val);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"写压力模式失败: {ex.Message}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +150,7 @@ namespace MembranePoreTester.ViewModels
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
for (int i = 1; i <= 3; i++)
|
||||
for (int i = 1; i <= 1; i++)
|
||||
{
|
||||
var station = new StationItem
|
||||
{
|
||||
|
||||
@@ -347,22 +347,16 @@ namespace MembranePoreTester.ViewModels
|
||||
set => SetProperty(ref _testMode, value);
|
||||
}
|
||||
|
||||
private int _selectedFlowModeIndex; // 0=大流量,1=小流量
|
||||
public int SelectedFlowModeIndex
|
||||
private string _selectedFlowModeIndex; // 0=大流量,1=小流量
|
||||
public string SelectedFlowModeIndex
|
||||
{
|
||||
get => _selectedFlowModeIndex;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _selectedFlowModeIndex, value))
|
||||
{
|
||||
ushort reg = StationId switch
|
||||
{
|
||||
1 => _plcConfig.FlowModeRegister1,
|
||||
2 => _plcConfig.FlowModeRegister2,
|
||||
3 => _plcConfig.FlowModeRegister3,
|
||||
_ => 0
|
||||
};
|
||||
Task.Run(async () => await _plcService.WriteSingleRegisterAsync(reg, (ushort)value));
|
||||
// 当选择变化时,写入 PLC 压力模式寄存器
|
||||
Task.Run(async () => await WriteFlowModeAsync(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -375,6 +369,18 @@ namespace MembranePoreTester.ViewModels
|
||||
set => SetProperty(ref _plotModel, value);
|
||||
}
|
||||
|
||||
private async Task WriteFlowModeAsync(string mode)
|
||||
{
|
||||
float val = mode == "大流量" ? 0.0f : 1.0f;
|
||||
try
|
||||
{
|
||||
await _plcService.WriteMultipleRegistersAsync(_plcConfig.PressureModeRegister, val);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"写流量模式失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePlot()
|
||||
{
|
||||
|
||||
@@ -4,8 +4,11 @@ using System.Runtime.CompilerServices;
|
||||
|
||||
namespace MembranePoreTester.ViewModels
|
||||
{
|
||||
public class ViewModelBase : INotifyPropertyChanged
|
||||
public class ViewModelBase : INotifyPropertyChanged, IDisposable
|
||||
{
|
||||
private bool _disposed = false;
|
||||
protected CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
@@ -30,5 +33,35 @@ namespace MembranePoreTester.ViewModels
|
||||
await App.PlcService.WriteSingleRegisterAsync(address, high);
|
||||
await App.PlcService.WriteSingleRegisterAsync((ushort)(address + 1), low);
|
||||
}
|
||||
|
||||
// 新增:安全执行异步方法(自动处理对象释放)
|
||||
protected async Task SafeExecuteAsync(Func<Task> action)
|
||||
{
|
||||
if (_disposed) return;
|
||||
try
|
||||
{
|
||||
await action();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// 正常取消
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"异步执行失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:检查是否已释放
|
||||
protected bool IsDisposed => _disposed;
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if (_disposed) return;
|
||||
_disposed = true;
|
||||
_cts?.Cancel();
|
||||
_cts?.Dispose();
|
||||
_cts = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user