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 中的调用逻辑。

相关推荐
云计算DevOps-韩老师1 小时前
Windows 10系统中找回MySQL 8的root密码
windows·mysql·adb
智汇优库2 小时前
Rabbitmq下载和安装(Windows系统,百度网盘)
windows·分布式·rabbitmq
冰茶_3 小时前
WPF之Button控件详解
大数据·学习·microsoft·c#·wpf
破刺不会编程3 小时前
系统的环境变量
linux·运维·服务器·windows
vortex54 小时前
Windows权限与icacls命令详解
windows·网络安全·渗透测试·操作系统
ABCDEEE74 小时前
人事管理系统6
windows·sql·mybatis
Linux运维老纪5 小时前
Ansible 守护 Windows 安全(Ansible Safeguards Windows Security)
linux·windows·网络安全·自动化·云计算·运维开发·asible
MyhEhud6 小时前
kotlin flatMap 变换函数的特点和使用场景
开发语言·windows·kotlin
冰茶_9 小时前
WPF TextBlock控件性能优化指南
学习·性能优化·wpf·控件