显示 CPU 与 ARM 占用率
简介
在一些占用系统资源较大的软件上可以增加 CPU 与 ARM 的占用率,用于美化界面的同时可以实时监视系统占用状况。
依赖于 PerformanceCounter 方法查询系统性能计数器,获取 CPU 与 ARM 基础信息,通过计算后获取占用率信息。
代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 
 | 
 
 public class SystemStateHelper
 {
 
 
 
 public SystemStateHelper()
 {
 Task.Run(() =>
 {
 PerformanceCounter CpuCounter = new PerformanceCounter("Processor Information", "% Processor Utility", "_Total");
 PerformanceCounter RamCounter = new PerformanceCounter("Memory", "Available MBytes");
 double TotalMemoryMBytesCapacity = GetTotalMemoryMBytesCapacity();
 
 while (true)
 {
 var cpuUsage = CpuCounter.NextValue();
 cpuUsage = cpuUsage >= 100 ? 100 : cpuUsage;
 
 var ramAvailable = RamCounter.NextValue();
 var memUsage = Math.Round((TotalMemoryMBytesCapacity - ramAvailable) / TotalMemoryMBytesCapacity, 4) * 100;
 memUsage = memUsage >= 100 ? 100 : memUsage;
 
 CpuCounterChange?.Invoke(cpuUsage);
 RamCounterChange?.Invoke(memUsage);
 Thread.Sleep(500);
 }
 });
 }
 
 
 
 
 
 public SystemStateHelper(int pid)
 {
 Task.Run(() =>
 {
 const float mega = 1024 * 1024;
 var vInstanceName = GetProcessInstanceName(pid);
 
 if (!string.IsNullOrEmpty(vInstanceName))
 {
 PerformanceCounter cpuPerformanceCounter = new PerformanceCounter("Process", "% Processor Time", vInstanceName);
 PerformanceCounter memoryPerformanceCounter = new PerformanceCounter("Process", "Working Set - Private", vInstanceName);
 
 while (true)
 {
 try
 {
 float mainCpu = cpuPerformanceCounter.NextValue() / Environment.ProcessorCount;
 mainCpu = mainCpu >= 100 ? 100 : mainCpu;
 
 float mainRam = memoryPerformanceCounter.NextValue() / mega;
 
 CpuCounterChange.Invoke(mainCpu);
 RamCounterChange.Invoke(mainRam);
 }
 catch (Exception)
 {
 
 }
 
 Thread.Sleep(500);
 }
 }
 });
 }
 
 
 
 
 public event Action<double> CpuCounterChange;
 
 
 
 
 public event Action<double> RamCounterChange;
 
 
 
 
 
 private double GetTotalMemoryMBytesCapacity()
 {
 using (var mc = new ManagementClass("Win32_PhysicalMemory"))
 {
 using (var moc = mc.GetInstances())
 {
 double totalCapacity = 0d;
 foreach (var mo in moc)
 {
 var moCapacity = long.Parse(mo.Properties["Capacity"].Value.ToString());
 totalCapacity += Math.Round(moCapacity / 1024.0 / 1024, 1);
 }
 return totalCapacity;
 }
 }
 }
 
 
 
 
 
 
 private string GetProcessInstanceName(int pid)
 {
 PerformanceCounterCategory processCategory = new PerformanceCounterCategory("Process");
 string[] runnedInstances = processCategory.GetInstanceNames();
 
 foreach (string runnedInstance in runnedInstances)
 {
 using (PerformanceCounter performanceCounter = new PerformanceCounter("Process", "ID Process", runnedInstance, true))
 {
 try
 {
 if ((int)performanceCounter?.RawValue == pid)
 {
 return runnedInstance;
 }
 }
 catch (Exception)
 { }
 }
 }
 return "";
 }
 }
 
 | 
调用说明
- 调用 SystemStateHelper() 获取全局占用率,返回结果为 CPU 与 ARM 占用率百分比,两位小数。
- 调用 SystemStateHelper(int pid) 获取指定 pid 进程占用率,返回结果为 CPU 占用率百分比,两位小数,ARM 占用字节,单位 MB。
- 通过 PerformanceCounter 方法查询占用率仅支持通过名字查询,但是运行多个相同名字的进程,会隐性增加命名后缀例如 #1、#2、#3,所以调用 GetProcessInstanceName(pid) 方法可以获取 pid 对应精确名称。
- 通过 pid 查询占用率时仅会查询自身进程的占用率,但是通常一个大型系统运行起来会调用多个不同进程组件,会存在与任务管理器显示不一致,可以先查询 pid 关联所有子线程,查询到占用率后叠加显示。  | 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | 
 
 public static Dictionary<int, string> GetAllProcess(int pid)
 {
 Dictionary<int, string> dicAllProcess = new Dictionary<int, string>();
 ManagementObjectSearcher searcher = new ManagementObjectSearcher($"Select * From Win32_Process Where ParentProcessID={pid}");
 foreach (ManagementObject mo in searcher.Get())
 {
 dicAllProcess.Add(int.Parse($"{mo["ProcessID"]}"), $"{mo["Name"]}");
 }
 return dicAllProcess;
 }
 
 |