WPF使用PerformanceCounter实现简单的性能检测器

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

screenshot

posted @ 2021-09-25 13:51  TruthHell  阅读(272)  评论(0编辑  收藏  举报