C#实时查看硬件使用率的实现方案

 更新时间:2026年05月12日 09:24:40   作者:yong9990  
文章主要介绍了如何通过C#进行硬件监控,包括实时监控本机硬件使用情况(CPU、内存、硬盘等),使用WPF进行实时显示,以及通过WMI监控远程Windows设备,同时,还提到了适用于Linux/ARM/嵌入式系统的监控方案,需要的朋友可以参考下

一、整体架构

┌─────────────────────────────────────────────────────────────┐
│                    硬件资源监控系统                         │
├─────────────────────────────────────────────────────────────┤
│  数据采集层   │  业务逻辑层   │  展示层        │  告警层    │
│               │               │                │            │
│  • PerformanceCounter        │  • 数据缓存    │  • WinForms │
│  • WMI (ManagementObject)   │  • 定时采样    │  • WPF      │
│  • System.Diagnostics       │  • 历史记录    │  • 上位机   │
│  • SNMP / SSH (远程)        │  • 阈值判断    │  • Web API  │
└─────────────────────────────────────────────────────────────┘

二、方案一:本机实时监控

适合:上位机、工业PC、边缘网关

2.1 核心类(HardwareMonitor.cs)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Management;
using System.Threading;
namespace HardwareMonitor
{
    public class HardwareMonitor
    {
        private readonly Timer _timer;
        private readonly int _intervalMs;
        public delegate void HardwareDataHandler(HardwareData data);
        public event HardwareDataHandler OnDataUpdated;
        public HardwareMonitor(int intervalMs = 1000)
        {
            _intervalMs = intervalMs;
            _timer = new Timer(Collect, null, Timeout.Infinite, Timeout.Infinite);
        }
        public void Start() => _timer.Change(0, _intervalMs);
        public void Stop() => _timer.Change(Timeout.Infinite, Timeout.Infinite);
        private void Collect(object state)
        {
            var data = new HardwareData
            {
                CpuUsage = GetCpuUsage(),
                MemoryUsedMb = GetMemoryUsed(),
                MemoryTotalMb = GetMemoryTotal(),
                DiskUsage = GetDiskUsage(),
                NetworkSentKBps = GetNetworkSent(),
                NetworkReceivedKBps = GetNetworkReceived(),
                Temperature = GetCpuTemperature()
            };
            OnDataUpdated?.Invoke(data);
        }
        #region CPU
        private float GetCpuUsage()
        {
            using var cpu = new PerformanceCounter("Processor", "% Processor Time", "_Total");
            cpu.NextValue();
            Thread.Sleep(100);
            return cpu.NextValue();
        }
        #endregion
        #region Memory
        private float GetMemoryUsed()
        {
            using var mem = new PerformanceCounter("Memory", "Committed Bytes");
            return mem.NextValue() / 1024 / 1024;
        }
        private float GetMemoryTotal()
        {
            using var mem = new PerformanceCounter("Memory", "Commit Limit");
            return mem.NextValue() / 1024 / 1024;
        }
        #endregion
        #region Disk
        private float GetDiskUsage()
        {
            using var disk = new PerformanceCounter("PhysicalDisk", "% Disk Time", "_Total");
            disk.NextValue();
            Thread.Sleep(100);
            return disk.NextValue();
        }
        #endregion
        #region Network
        private float GetNetworkSent()
        {
            using var net = new PerformanceCounter("Network Interface", "Bytes Sent/sec", GetNetworkCard());
            return net.NextValue() / 1024;
        }
        private float GetNetworkReceived()
        {
            using var net = new PerformanceCounter("Network Interface", "Bytes Received/sec", GetNetworkCard());
            return net.NextValue() / 1024;
        }
        private string GetNetworkCard()
        {
            using var searcher = new ManagementObjectSearcher("SELECT Name FROM Win32_NetworkAdapter WHERE NetEnabled = true");
            foreach (ManagementObject obj in searcher.Get())
                return obj["Name"].ToString();
            return "";
        }
        #endregion
        #region Temperature (WMI)
        private float GetCpuTemperature()
        {
            try
            {
                using var searcher = new ManagementObjectSearcher(@"root\WMI", "SELECT CurrentTemperature FROM MSAcpi_ThermalZoneTemperature");
                foreach (ManagementObject obj in searcher.Get())
                {
                    var temp = Convert.ToDouble(obj["CurrentTemperature"].ToString());
                    return (float)(temp / 10.0 - 273.15); // Kelvin → Celsius
                }
            }
            catch { }
            return 0;
        }
        #endregion
    }
    public class HardwareData
    {
        public float CpuUsage { get; set; }
        public float MemoryUsedMb { get; set; }
        public float MemoryTotalMb { get; set; }
        public float DiskUsage { get; set; }
        public float NetworkSentKBps { get; set; }
        public float NetworkReceivedKBps { get; set; }
        public float Temperature { get; set; }
        public override string ToString()
        {
            return $"CPU:{CpuUsage:F1}%  MEM:{MemoryUsedMb:F0}/{MemoryTotalMb:F0}MB  DISK:{DiskUsage:F1}%  TEMP:{Temperature:F1}℃";
        }
    }
}

三、方案二:WPF 实时显示

3.1 MainWindow.xaml

<Window x:Class="HardwareMonitor.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        Title="硬件实时监控" Height="320" Width="400">
    <StackPanel Margin="20">
        <TextBlock Text="CPU 使用率" FontWeight="Bold"/>
        <ProgressBar x:Name="CpuBar" Height="20" Maximum="100"/>
        <TextBlock x:Name="CpuText"/>
        <TextBlock Text="内存使用" FontWeight="Bold" Margin="0,10,0,0"/>
        <ProgressBar x:Name="MemBar" Height="20" Maximum="100"/>
        <TextBlock x:Name="MemText"/>
        <TextBlock Text="硬盘使用" FontWeight="Bold" Margin="0,10,0,0"/>
        <ProgressBar x:Name="DiskBar" Height="20" Maximum="100"/>
        <TextBlock Text="CPU 温度" FontWeight="Bold" Margin="0,10,0,0"/>
        <TextBlock x:Name="TempText" FontSize="16" Foreground="Red"/>
    </StackPanel>
</Window>

3.2 MainWindow.xaml.cs

using System.Windows;

namespace HardwareMonitor
{
    public partial class MainWindow : Window
    {
        private readonly HardwareMonitor _monitor;

        public MainWindow()
        {
            InitializeComponent();
            _monitor = new HardwareMonitor(1000);
            _monitor.OnDataUpdated += UpdateUI;
            _monitor.Start();
        }

        private void UpdateUI(HardwareData data)
        {
            Dispatcher.Invoke(() =>
            {
                CpuBar.Value = data.CpuUsage;
                CpuText.Text = $"{data.CpuUsage:F1}%";

                MemBar.Value = data.MemoryUsedMb / data.MemoryTotalMb * 100;
                MemText.Text = $"{data.MemoryUsedMb:F0} MB / {data.MemoryTotalMb:F0} MB";

                DiskBar.Value = data.DiskUsage;
                TempText.Text = $"{data.Temperature:F1} ℃";
            });
        }
    }
}

参考代码 C# 实时查看 硬件使用率(CPU/内存/硬盘等) www.youwenfan.com/contentcsu/62418.html

四、方案三:远程设备监控

4.1 通过 WMI 监控远程 Windows 设备

public static float GetRemoteCpuUsage(string ip, string user, string pwd)
{
    var options = new ConnectionOptions
    {
        Username = user,
        Password = pwd,
        Impersonation = ImpersonationLevel.Impersonate
    };

    var scope = new ManagementScope($"\\\\{ip}\\root\\cimv2", options);
    scope.Connect();

    using var searcher = new ManagementObjectSearcher(
        scope, new ObjectQuery("SELECT LoadPercentage FROM Win32_Processor"));

    foreach (ManagementObject obj in searcher.Get())
        return Convert.ToSingle(obj["LoadPercentage"]);

    return 0;
}

五、Linux / ARM / 嵌入式(STM32 上位机)

// Linux
cat /proc/cpuinfo
cat /proc/meminfo
df -h
public static float GetLinuxCpuUsage()
{
    var cpu = File.ReadAllText("/proc/stat").Split('\n')[0];
    return ParseCpu(cpu);
}

以上就是C#实时查看硬件使用率的实现方案的详细内容,更多关于C#实时查看硬件使用率的资料请关注脚本之家其它相关文章!

相关文章

  • C#实现多文件打包压缩(.Net Core)

    C#实现多文件打包压缩(.Net Core)

    本文详细讲解了.Net Core框架下C#实现多文件打包压缩的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • C#实现两个richtextbox控件滚动条同步滚动的简单方法

    C#实现两个richtextbox控件滚动条同步滚动的简单方法

    这篇文章主要给大家介绍了C#实现两个richtextbox控件滚动条同步滚动的简单方法,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-05-05
  • 详解C# winform ListView的基本操作

    详解C# winform ListView的基本操作

    本文主要介绍了C# winform ListView的基本操作,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • C#基础知识之new关键字介绍

    C#基础知识之new关键字介绍

    在 C# 中,new 关键字可用作运算符、修饰符或约束,本文主要介绍这三种用法。
    2016-04-04
  • C#实现解压GZip文件的方法

    C#实现解压GZip文件的方法

    这篇文章主要介绍了C#实现解压GZip文件的方法,涉及C#操作压缩文件的技巧,需要的朋友可以参考下
    2015-05-05
  • C# RabbitMQ的使用详解

    C# RabbitMQ的使用详解

    本文主要介绍了C# RabbitMQ的使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • C#使用dynamic一行代码实现反射操作

    C#使用dynamic一行代码实现反射操作

    dynamic的出现让C#具有了弱语言类型的特性。编译器在编译的时候不再对类型进行检查,编译时默认dynamic对象支持你想要的任何特性,这篇文章主要介绍了C#用dynamic一行代码实现反射操作,需要的朋友可以参考下
    2023-04-04
  • c#中XML解析文件出错解决方法

    c#中XML解析文件出错解决方法

    在解析xml时,经常因为文件中含特殊字符而解析失败。原因有两个:一是内容中含有XML预定义好的实体,二是内容中含有低位非打印字符
    2014-08-08
  • C#分析URL参数并获取参数和值对应列表的方法

    C#分析URL参数并获取参数和值对应列表的方法

    这篇文章主要介绍了C#分析URL参数获取参数和值对应列表的方法,涉及C#进行URL分析及正则表达式的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • 无法从 int? 转换为 int 运行时出现错误

    无法从 int? 转换为 int 运行时出现错误

    无法从"int?"转换为"int" ,在运行时会出现错误,通过强制类型转换(int)便可解决
    2014-05-05

最新评论