WPF使用PerformanceCounter实现简单的性能检测器
PerformanceCounter
可以参考我之前的文章:C#使用PerformanceCounter获取CPU和内存利用率。
WPF界面
<Window x:Class="WpfUsage.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfUsage"
mc:Ignorable="d"
Title="Computer Status" Height="150" Width="300" WindowStyle="SingleBorderWindow" WindowStartupLocation="CenterScreen" Icon="favicon.ico" Topmost="True" ResizeMode="CanMinimize">
<Grid ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="CPU:" />
<Label Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="3" x:Name="CpuUsage" Content="N/A" />
<Label Grid.Row="1" Grid.Column="0" Content="Mem:" />
<Label Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" x:Name="MemUsage" Content="N/A" />
<Label Grid.Row="2" Grid.Column="0" Content="Interface:" />
<ComboBox Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" x:Name="ComBoxInterfaces" SelectionChanged="ComBoxInterfaces_SelectionChanged" HorizontalAlignment="Left" VerticalAlignment="Center" />
<Label Grid.Row="3" Grid.Column="0" Content="RX:" />
<Label Grid.Row="3" Grid.Column="1" x:Name="NetRxUsage" Content="N/A" />
<Label Grid.Row="3" Grid.Column="2" Content="TX:" />
<Label Grid.Row="3" Grid.Column="3" x:Name="NetTxUsage" Content="N/A" />
</Grid>
</Window>
逻辑
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace WpfUsage
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly PerformanceCounter cpuCounter;
private readonly PerformanceCounter memAvailableCounter;
private readonly ulong memTotal = 0;
private readonly Dictionary<string, PerformanceCounter> netRxCounters;
private readonly Dictionary<string, PerformanceCounter> netTxCounters;
private readonly string[] interfaces;
private int interfaceIdx = -1;
private readonly DispatcherTimer timer;
private const int KB = 1024;
private const int MB = KB * 1024;
private const int GB = MB * 1024;
public MainWindow()
{
InitializeComponent();
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
//memCounter = new PerformanceCounter("Memory", "% Committed Bytes In Use");
memAvailableCounter = new PerformanceCounter("Memory", "Available Bytes");
netRxCounters = new Dictionary<string, PerformanceCounter>();
netTxCounters = new Dictionary<string, PerformanceCounter>();
var memMC = new ManagementClass("Win32_PhysicalMemory");
foreach (var memMo in memMC.GetInstances())
{
memTotal += (ulong)memMo.GetPropertyValue("Capacity");
memMo.Dispose();
}
memMC.Dispose();
interfaces = PerformanceCounterCategory.GetCategories().Where(category => category.CategoryName == "Network Interface").FirstOrDefault()?.GetInstanceNames();
if (interfaces != null && interfaces.Length > 0)
{
Array.Sort(interfaces);
ComBoxInterfaces.ItemsSource = interfaces;
foreach (string interfaceName in interfaces)
{
netRxCounters.Add(interfaceName, new PerformanceCounter("Network Interface", "Bytes Received/sec", interfaceName));
netTxCounters.Add(interfaceName, new PerformanceCounter("Network Interface", "Bytes Sent/sec", interfaceName));
}
SetActiveInterface();
}
timer = new DispatcherTimer
{
Interval = new TimeSpan(0, 0, 1),
IsEnabled = true
};
timer.Tick += Timer_Tick;
timer.Start();
}
private void SetActiveInterface()
{
for (int i = 0; i < interfaces.Length; i++)
{
// simple check: not good enough
if (netRxCounters[interfaces[i]].NextValue() > 0)
{
interfaceIdx = i;
ComBoxInterfaces.SelectedIndex = i;
return;
}
}
interfaceIdx = 0;
ComBoxInterfaces.SelectedIndex = 0;
}
private void Timer_Tick(object sender, EventArgs e)
{
CpuUsage.Content = $"{cpuCounter.NextValue():F2}%";
//MemUsage.Content = $"{memCounter.NextValue():F2}% (Available: {memAvailableCounter.NextValue() / GB:F2}GB)";
var memAvailable = memAvailableCounter.NextValue();
MemUsage.Content = $"{(memTotal - memAvailable) / memTotal:P2} (Available: {memAvailable / GB:F2}GB)";
if (interfaceIdx != -1)
{
NetRxUsage.Content = FormatRxTxRate(netRxCounters[interfaces[interfaceIdx]].NextValue());
NetTxUsage.Content = FormatRxTxRate(netTxCounters[interfaces[interfaceIdx]].NextValue());
}
}
private static string FormatRxTxRate(float rate)
{
if (rate < KB)
{
return $"{rate:F2}B/s";
}
else if (rate < MB)
{
return $"{rate / KB:F2}KB/s";
}
else if (rate < GB)
{
return $"{rate / MB:F2}MB/s";
}
else
{
return $"{rate / GB:F2}GB/s";
}
}
private void ComBoxInterfaces_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
interfaceIdx = ComBoxInterfaces.SelectedIndex;
}
}
}
效果
查看完整代码:ComputerStatusWpf