Files
2026-03-28 16:48:41 +08:00

143 lines
4.2 KiB
C#

using MembranePoreTester.Communication;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace MembranePoreTester.ViewModels
{
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)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
protected async Task WriteFloatAsync(ushort address, float value)
{
byte[] bytes = BitConverter.GetBytes(value);
if (BitConverter.IsLittleEndian) Array.Reverse(bytes);
ushort high = (ushort)((bytes[0] << 8) | bytes[1]);
ushort low = (ushort)((bytes[2] << 8) | bytes[3]);
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}");
}
}
public bool IsInDesignMode()
{
return System.ComponentModel.DesignerProperties.GetIsInDesignMode(
new System.Windows.DependencyObject());
}
// ========== 错误抑制机制 ==========
private class ErrorRecord
{
public bool HasError { get; set; }
public DateTime LastErrorTime { get; set; }
}
private readonly Dictionary<string, ErrorRecord> _errorRecords = new();
/// <summary>
/// 安全执行异步操作,自动抑制重复错误
/// </summary>
protected async Task<bool> SafeExecuteAsync(string operationKey, Func<Task> action, int suppressSeconds = 3)
{
// 检查是否需要抑制
if (_errorRecords.TryGetValue(operationKey, out var record) && record.HasError)
{
if ((DateTime.Now - record.LastErrorTime).TotalSeconds < suppressSeconds)
{
return false;
}
}
try
{
await action();
// 成功,清除错误记录
if (_errorRecords.TryGetValue(operationKey, out var successRecord))
{
successRecord.HasError = false;
}
return true;
}
catch (Exception ex)
{
// 记录错误
if (!_errorRecords.TryGetValue(operationKey, out var errorRecord))
{
errorRecord = new ErrorRecord();
_errorRecords[operationKey] = errorRecord;
}
errorRecord.HasError = true;
errorRecord.LastErrorTime = DateTime.Now;
// 静默记录到输出窗口
Debug.WriteLine($"[{DateTime.Now:HH:mm:ss}] {operationKey} 失败: {ex.Message}");
return false;
}
}
// 新增:检查是否已释放
protected bool IsDisposed => _disposed;
public virtual void Dispose()
{
if (_disposed) return;
_disposed = true;
_cts?.Cancel();
_cts?.Dispose();
_cts = null;
}
}
}