WPF 程序监控硬件设备状态变化的实现方案

以下是一个完整的 C# WPF 程序实现方案,用于监控硬件设备状态变化(基于设备 SDK API)。我们将分步骤实现,包含状态轮询、事件通知、UI 绑定和错误处理。


1. 项目结构设计

cs 复制代码
HardwareMonitor/
├── Models/               # 数据模型
│   └── DeviceStatus.cs
├── Services/            # 硬件服务层
│   ├── IDeviceService.cs
│   └── DeviceService.cs
├── ViewModels/          # MVVM 视图模型
│   └── MainViewModel.cs
├── Views/               # 用户界面
│   └── MainWindow.xaml
└── App.xaml             # 应用程序入口

2. 实现步骤

(1) 定义设备状态模型
cs 复制代码
// Models/DeviceStatus.cs
public class DeviceStatus : INotifyPropertyChanged
{
    private bool _isConnected;
    public bool IsConnected
    {
        get => _isConnected;
        set { _isConnected = value; OnPropertyChanged(); }
    }

    private double _temperature;
    public double Temperature
    {
        get => _temperature;
        set { _temperature = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler? PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string? name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}
(2) 封装设备 SDK API
cs 复制代码
// Services/IDeviceService.cs
public interface IDeviceService
{
    DeviceStatus CurrentStatus { get; }
    event EventHandler<DeviceStatus> StatusChanged;
    void StartMonitoring();
    void StopMonitoring();
}

// Services/DeviceService.cs
public class DeviceService : IDeviceService, IDisposable
{
    private readonly Timer _pollingTimer;
    private readonly DeviceSDK _sdk; // 假设这是硬件SDK的类

    public DeviceStatus CurrentStatus { get; } = new DeviceStatus();
    public event EventHandler<DeviceStatus>? StatusChanged;

    public DeviceService()
    {
        _sdk = new DeviceSDK(); // 初始化SDK
        _pollingTimer = new Timer(UpdateStatus, null, Timeout.Infinite, 1000);
    }

    public void StartMonitoring() => _pollingTimer.Change(0, 1000); // 每秒轮询

    public void StopMonitoring() => _pollingTimer.Change(Timeout.Infinite, Timeout.Infinite);

    private void UpdateStatus(object? state)
    {
        try
        {
            // 调用SDK获取状态
            CurrentStatus.IsConnected = _sdk.GetConnectionStatus();
            CurrentStatus.Temperature = _sdk.ReadTemperature();

            // 触发事件
            StatusChanged?.Invoke(this, CurrentStatus);
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"监控错误: {ex.Message}");
        }
    }

    public void Dispose()
    {
        _pollingTimer.Dispose();
        _sdk.Disconnect();
    }
}
(3) 实现 ViewModel
cs 复制代码
// ViewModels/MainViewModel.cs
public class MainViewModel : INotifyPropertyChanged
{
    private readonly IDeviceService _deviceService;
    private string _statusMessage = "等待连接...";

    public DeviceStatus Status { get; }
    public string StatusMessage
    {
        get => _statusMessage;
        set { _statusMessage = value; OnPropertyChanged(); }
    }

    public ICommand StartMonitoringCommand { get; }
    public ICommand StopMonitoringCommand { get; }

    public MainViewModel(IDeviceService deviceService)
    {
        _deviceService = deviceService;
        Status = _deviceService.CurrentStatus;

        // 命令绑定
        StartMonitoringCommand = new RelayCommand(() =>
        {
            _deviceService.StartMonitoring();
            StatusMessage = "监控中...";
        });

        StopMonitoringCommand = new RelayCommand(() =>
        {
            _deviceService.StopMonitoring();
            StatusMessage = "已停止";
        });

        // 订阅状态变化事件
        _deviceService.StatusChanged += (s, e) => 
        {
            StatusMessage = e.IsConnected ? "设备在线" : "设备离线";
        };
    }

    public event PropertyChangedEventHandler? PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string? name = null)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
(4) 创建 WPF 界面
XML 复制代码
<!-- Views/MainWindow.xaml -->
<Window x:Class="HardwareMonitor.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="硬件监控" Height="300" Width="400">
    <Grid Margin="10">
        <StackPanel>
            <TextBlock Text="{Binding StatusMessage}" FontSize="16" Margin="0,10"/>
            
            <Border Background="{Binding Status.IsConnected, Converter={StaticResource BoolToBrushConverter}}"
                    CornerRadius="5" Padding="10" Margin="0,10">
                <TextBlock Text="{Binding Status.IsConnected, Converter={StaticResource BoolToStatusConverter}}"
                           HorizontalAlignment="Center"/>
            </Border>

            <TextBlock Text="{Binding Status.Temperature, StringFormat='温度: {0}°C'}" 
                       Margin="0,10"/>

            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                <Button Content="开始监控" Command="{Binding StartMonitoringCommand}" Margin="5" Width="100"/>
                <Button Content="停止监控" Command="{Binding StopMonitoringCommand}" Margin="5" Width="100"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>
(5) 依赖注入配置
cs 复制代码
// App.xaml.cs
public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        // 配置DI容器
        var services = new ServiceCollection();
        services.AddSingleton<IDeviceService, DeviceService>();
        services.AddTransient<MainViewModel>();
        services.AddTransient<MainWindow>();

        var provider = services.BuildServiceProvider();

        // 启动主窗口
        var mainWindow = provider.GetRequiredService<MainWindow>();
        mainWindow.DataContext = provider.GetRequiredService<MainViewModel>();
        mainWindow.Show();
    }
}

3. 关键功能实现

(1) 状态轮询优化
cs 复制代码
// 使用CancellationToken实现可控轮询
private async Task RunPollingAsync(CancellationToken token)
{
    while (!token.IsCancellationRequested)
    {
        UpdateStatus(null);
        await Task.Delay(1000, token); // 异步延迟
    }
}
(2) SDK 异常处理
cs 复制代码
private void UpdateStatus(object? state)
{
    try
    {
        // 添加超时控制
        using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));
        var status = Task.Run(() => _sdk.GetStatus(), cts.Token).Result;
        
        // 更新状态...
    }
    catch (OperationCanceledException)
    {
        StatusMessage = "SDK响应超时";
    }
    catch (Exception ex)
    {
        Debug.WriteLine($"SDK错误: {ex.Message}");
    }
}
(3) UI 绑定转换器
cs 复制代码
// BoolToBrushConverter.cs
public class BoolToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? Brushes.LightGreen : Brushes.LightPink;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

4. 部署与测试

硬件 SDK 集成
  1. 将厂商提供的 SDK DLL 放入 lib/ 目录

  2. 在项目中添加引用:

XML 复制代码
<ItemGroup>
  <Reference Include="DeviceSDK" HintPath="lib\DeviceSDK.dll" />
</ItemGroup>
测试方案
测试类型 方法 预期结果
正常连接测试 模拟SDK返回有效数据 UI实时更新状态
断开连接测试 关闭硬件设备 显示"设备离线"
压力测试 高频调用SDK API 不出现UI卡顿或内存泄漏
异常测试 抛出SDK异常 显示错误且不崩溃

5. 扩展功能建议

  1. 历史数据记录
cs 复制代码
public void LogStatus(DeviceStatus status)
{
    File.AppendAllText("log.txt", 
        $"{DateTime.Now}: {status.Temperature}°C, Connected={status.IsConnected}\n");
}
  1. 阈值报警
cs 复制代码
if (CurrentStatus.Temperature > 80)
{
    PlayAlertSound();
    ShowToast("温度过高!");
}
  1. 远程监控
cs 复制代码
// 使用SignalR将状态推送到Web端
await _hubConnection.SendAsync("ReportStatus", CurrentStatus);

系统优点:

  • 分层清晰(MVVM + 服务隔离)

  • 响应灵敏(异步轮询 + 事件驱动)

  • 健壮可靠(完备的错误处理)

  • 易于扩展(依赖注入支持)

的硬件监控系统。实际开发时,请根据具体 SDK API 调整 DeviceService 中的调用逻辑。

相关推荐
c#上位机13 小时前
wpf之Border
c#·wpf
SunflowerCoder13 小时前
WPF迁移avalonia之图像处理(一)
图像处理·wpf·avalonia
小韩博14 小时前
Windows 权限提升(一)
windows
周杰伦fans14 小时前
WPF中的DataContext以及常见的绑定方式
wpf
魔都吴所谓15 小时前
【Python】根据开始时间、结束时间计算中间时间
开发语言·windows·python
syty202016 小时前
flink 伪代码
java·windows·flink
IDOlaoluo17 小时前
TortoiseGit 2.4.0.0 64位安装教程(附详细步骤和Git配置 附安装包)
windows
知行力17 小时前
【GitHub每日速递】不止 TeamViewer 替代!RustDesk 与 PowerToys,Windows 效率神器
windows·github·teamviewer
怒码ing19 小时前
List<?>和List<Object>区别
windows·python·list
豆浩宇20 小时前
学习PaddlePaddle--环境配置-Windows 11 + RTX 4060
人工智能·windows·深度学习·学习·目标检测·计算机视觉·paddlepaddle