利用WPF实现系统资源监控的完整代码
作者:code_shenbing
一、引言
在现代软件开发中,系统资源监控是系统管理、性能分析和故障诊断的重要工具。WPF(Windows Presentation Foundation)凭借其强大的数据绑定、样式模板和动画功能,是构建现代化、美观实用的系统监控应用的理想选择。本文将详细介绍如何使用WPF创建一个功能全面的系统资源监控仪表盘。
二、整体架构设计
2.1 系统架构
┌─────────────────────────────────────────────────────┐
│ WPF UI层 (视图层) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ CPU监控 │ │ 内存监控 │ │ 磁盘监控 │ │ 网络监控 │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────┐
│ 监控服务层 (ViewModel) │
│ ┌─────────────────────────────────────────────┐ │
│ │ ResourceMonitorService (单例模式) │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────┐
│ 数据采集层 (PerformanceCounter) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ CPU │ │ Memory │ │ Disk │ │ Network │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────┘
2.2 技术要点
- WPF MVVM模式:使用Prism或MVVM Light框架
- 数据绑定:实时更新监控数据
- 自定义控件:创建仪表盘、进度条等可视化组件
- 图表控件:使用LiveCharts或OxyPlot绘制历史趋势
- 多线程:使用BackgroundWorker或async/await避免UI阻塞
- 系统API:使用PerformanceCounter、WMI、Win32 API
三、完整代码实现
3.1 实体模型层
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SystemResouceWpfApp.Models;
public class SystemResourceInfo : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// CPU信息
private float _cpuUsage;
public float CpuUsage
{
get => _cpuUsage;
set
{
if (Math.Abs(_cpuUsage - value) > 0.01)
{
_cpuUsage = value;
OnPropertyChanged(nameof(CpuUsage));
}
}
}
private List<ProcessInfo> _topProcesses = new List<ProcessInfo>();
public List<ProcessInfo> TopProcesses
{
get => _topProcesses;
set
{
_topProcesses = value;
OnPropertyChanged(nameof(TopProcesses));
}
}
// 内存信息
private float _memoryUsage;
public float MemoryUsage
{
get => _memoryUsage;
set
{
if (Math.Abs(_memoryUsage - value) > 0.01)
{
_memoryUsage = value;
OnPropertyChanged(nameof(MemoryUsage));
}
}
}
private ulong _totalMemory;
public ulong TotalMemory
{
get => _totalMemory;
set
{
if (_totalMemory != value)
{
_totalMemory = value;
OnPropertyChanged(nameof(TotalMemory));
}
}
}
private ulong _usedMemory;
public ulong UsedMemory
{
get => _usedMemory;
set
{
if (_usedMemory != value)
{
_usedMemory = value;
OnPropertyChanged(nameof(UsedMemory));
}
}
}
// 磁盘信息
private List<DiskInfo> _diskInfos = new List<DiskInfo>();
public List<DiskInfo> DiskInfos
{
get => _diskInfos;
set
{
_diskInfos = value;
OnPropertyChanged(nameof(DiskInfos));
}
}
// 网络信息
private float _networkUploadSpeed;
public float NetworkUploadSpeed
{
get => _networkUploadSpeed;
set
{
if (Math.Abs(_networkUploadSpeed - value) > 0.01)
{
_networkUploadSpeed = value;
OnPropertyChanged(nameof(NetworkUploadSpeed));
}
}
}
private float _networkDownloadSpeed;
public float NetworkDownloadSpeed
{
get => _networkDownloadSpeed;
set
{
if (Math.Abs(_networkDownloadSpeed - value) > 0.01)
{
_networkDownloadSpeed = value;
OnPropertyChanged(nameof(NetworkDownloadSpeed));
}
}
}
// 系统信息
private DateTime _systemUptime;
public DateTime SystemUptime
{
get => _systemUptime;
set
{
if (_systemUptime != value)
{
_systemUptime = value;
OnPropertyChanged(nameof(SystemUptime));
}
}
}
}
public class ProcessInfo : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public int ProcessId { get; set; }
public string ProcessName { get; set; }
private float _cpuPercent;
public float CpuPercent
{
get => _cpuPercent;
set
{
if (Math.Abs(_cpuPercent - value) > 0.01)
{
_cpuPercent = value;
OnPropertyChanged(nameof(CpuPercent));
}
}
}
private float _memoryMB;
public float MemoryMB
{
get => _memoryMB;
set
{
if (Math.Abs(_memoryMB - value) > 0.01)
{
_memoryMB = value;
OnPropertyChanged(nameof(MemoryMB));
}
}
}
}
public class DiskInfo : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string DriveLetter { get; set; }
public string DriveName { get; set; }
private float _usagePercent;
public float UsagePercent
{
get => _usagePercent;
set
{
if (Math.Abs(_usagePercent - value) > 0.01)
{
_usagePercent = value;
OnPropertyChanged(nameof(UsagePercent));
}
}
}
private ulong _totalSizeGB;
public ulong TotalSizeGB
{
get => _totalSizeGB;
set
{
if (_totalSizeGB != value)
{
_totalSizeGB = value;
OnPropertyChanged(nameof(TotalSizeGB));
}
}
}
private ulong _freeSpaceGB;
public ulong FreeSpaceGB
{
get => _freeSpaceGB;
set
{
if (_freeSpaceGB != value)
{
_freeSpaceGB = value;
OnPropertyChanged(nameof(FreeSpaceGB));
}
}
}
private float _readSpeed;
public float ReadSpeed
{
get => _readSpeed;
set
{
if (Math.Abs(_readSpeed - value) > 0.01)
{
_readSpeed = value;
OnPropertyChanged(nameof(ReadSpeed));
}
}
}
private float _writeSpeed;
public float WriteSpeed
{
get => _writeSpeed;
set
{
if (Math.Abs(_writeSpeed - value) > 0.01)
{
_writeSpeed = value;
OnPropertyChanged(nameof(WriteSpeed));
}
}
}
}
3.2 监控服务层
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using SystemResouceWpfApp.Models;
namespace SystemResouceWpfApp.Services;
public class SystemMonitorService : INotifyPropertyChanged
{
#region Singleton Instance
private static readonly Lazy<SystemMonitorService> _instance =
new Lazy<SystemMonitorService>(() => new SystemMonitorService());
public static SystemMonitorService Instance => _instance.Value;
#endregion
#region Native Methods
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetSystemTimes(
out long lpIdleTime,
out long lpKernelTime,
out long lpUserTime);
[DllImport("psapi.dll")]
private static extern bool GetProcessMemoryInfo(
IntPtr Process,
out PROCESS_MEMORY_COUNTERS ppsmemCounters,
uint cb);
[StructLayout(LayoutKind.Sequential, Size = 72)]
private struct PROCESS_MEMORY_COUNTERS
{
public uint cb;
public uint PageFaultCount;
public UIntPtr PeakWorkingSetSize;
public UIntPtr WorkingSetSize;
public UIntPtr QuotaPeakPagedPoolUsage;
public UIntPtr QuotaPagedPoolUsage;
public UIntPtr QuotaPeakNonPagedPoolUsage;
public UIntPtr QuotaNonPagedPoolUsage;
public UIntPtr PagefileUsage;
public UIntPtr PeakPagefileUsage;
}
#endregion
#region Fields
private readonly PerformanceCounter _cpuCounter;
private readonly PerformanceCounter _memoryCounter;
private readonly PerformanceCounter _diskReadCounter;
private readonly PerformanceCounter _diskWriteCounter;
private readonly List<PerformanceCounter> _networkCounters = new List<PerformanceCounter>();
private readonly SystemResourceInfo _resourceInfo = new SystemResourceInfo();
private readonly List<PerformanceCounter> _processCpuCounters = new List<PerformanceCounter>();
private readonly Dictionary<int, ProcessInfo> _processCache = new Dictionary<int, ProcessInfo>();
private CancellationTokenSource _monitoringCts;
private Task _monitoringTask;
private bool _isMonitoring;
// CPU计算相关
private long _prevIdleTime;
private long _prevKernelTime;
private long _prevUserTime;
// 网络计算相关
private Dictionary<string, (long Received, long Sent)> _prevNetworkValues =
new Dictionary<string, (long, long)>();
#endregion
#region Properties
public SystemResourceInfo ResourceInfo => _resourceInfo;
public bool IsMonitoring
{
get => _isMonitoring;
private set
{
if (_isMonitoring != value)
{
_isMonitoring = value;
OnPropertyChanged(nameof(IsMonitoring));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Constructor
private SystemMonitorService()
{
try
{
// 初始化性能计数器
_cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
_memoryCounter = new PerformanceCounter("Memory", "Available MBytes");
// 初始化磁盘计数器
_diskReadCounter = new PerformanceCounter("PhysicalDisk", "Disk Read Bytes/sec", "_Total");
_diskWriteCounter = new PerformanceCounter("PhysicalDisk", "Disk Write Bytes/sec", "_Total");
// 初始化网络计数器
InitializeNetworkCounters();
// 初始化进程计数器
InitializeProcessCounters();
// 获取总内存
GetTotalMemory();
// 获取磁盘信息
GetDiskInfo();
}
catch (Exception ex)
{
Debug.WriteLine($"性能计数器初始化失败: {ex.Message}");
}
}
#endregion
#region Public Methods
public void StartMonitoring(int intervalMs = 1000)
{
if (IsMonitoring) return;
_monitoringCts = new CancellationTokenSource();
_monitoringTask = Task.Run(() => MonitorLoop(intervalMs, _monitoringCts.Token));
IsMonitoring = true;
}
public void StopMonitoring()
{
if (!IsMonitoring) return;
_monitoringCts?.Cancel();
_monitoringTask?.Wait();
IsMonitoring = false;
}
public SystemResourceInfo GetCurrentStatus()
{
UpdateSystemResources();
return _resourceInfo;
}
public List<ProcessInfo> GetTopProcessesByCpu(int count = 5)
{
UpdateProcessInfo();
return _resourceInfo.TopProcesses
.OrderByDescending(p => p.CpuPercent)
.Take(count)
.ToList();
}
public List<ProcessInfo> GetTopProcessesByMemory(int count = 5)
{
UpdateProcessInfo();
return _resourceInfo.TopProcesses
.OrderByDescending(p => p.MemoryMB)
.Take(count)
.ToList();
}
#endregion
#region Private Methods
private void InitializeNetworkCounters()
{
try
{
var category = new PerformanceCounterCategory("Network Interface");
var instances = category.GetInstanceNames();
foreach (var instance in instances)
{
// 排除虚拟适配器和回环接口
if (instance.Contains("Loopback") ||
instance.Contains("isatap") ||
instance.Contains("Teredo"))
continue;
var receivedCounter = new PerformanceCounter("Network Interface",
"Bytes Received/sec", instance);
var sentCounter = new PerformanceCounter("Network Interface",
"Bytes Sent/sec", instance);
_networkCounters.Add(receivedCounter);
_networkCounters.Add(sentCounter);
}
}
catch (Exception ex)
{
Debug.WriteLine($"网络计数器初始化失败: {ex.Message}");
}
}
private void InitializeProcessCounters()
{
try
{
var processes = Process.GetProcesses();
foreach (var process in processes)
{
try
{
var counter = new PerformanceCounter("Process", "% Processor Time",
process.ProcessName, true);
_processCpuCounters.Add(counter);
}
catch
{
// 忽略无权限访问的进程
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"进程计数器初始化失败: {ex.Message}");
}
}
private void GetTotalMemory()
{
try
{
using (var searcher = new ManagementObjectSearcher("SELECT TotalVisibleMemorySize FROM Win32_OperatingSystem"))
{
foreach (var obj in searcher.Get())
{
if (ulong.TryParse(obj["TotalVisibleMemorySize"]?.ToString(), out ulong totalMemoryKB))
{
_resourceInfo.TotalMemory = totalMemoryKB / 1024; // 转换为MB
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"获取总内存失败: {ex.Message}");
}
}
private void GetDiskInfo()
{
try
{
var diskInfos = new List<DiskInfo>();
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3"))
{
foreach (var disk in searcher.Get())
{
var diskInfo = new DiskInfo
{
DriveLetter = disk["DeviceID"]?.ToString() ?? "Unknown",
DriveName = disk["VolumeName"]?.ToString() ?? "Local Disk"
};
if (ulong.TryParse(disk["Size"]?.ToString(), out ulong totalSize))
{
diskInfo.TotalSizeGB = totalSize / (1024 * 1024 * 1024);
}
if (ulong.TryParse(disk["FreeSpace"]?.ToString(), out ulong freeSpace))
{
diskInfo.FreeSpaceGB = freeSpace / (1024 * 1024 * 1024);
}
if (diskInfo.TotalSizeGB > 0)
{
diskInfo.UsagePercent = 100f -
((float)diskInfo.FreeSpaceGB / diskInfo.TotalSizeGB * 100);
}
diskInfos.Add(diskInfo);
}
}
_resourceInfo.DiskInfos = diskInfos;
}
catch (Exception ex)
{
Debug.WriteLine($"获取磁盘信息失败: {ex.Message}");
}
}
private async Task MonitorLoop(int intervalMs, CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
try
{
UpdateSystemResources();
await Task.Delay(intervalMs, cancellationToken);
}
catch (TaskCanceledException)
{
break;
}
catch (Exception ex)
{
Debug.WriteLine($"监控循环错误: {ex.Message}");
}
}
}
private void UpdateSystemResources()
{
try
{
UpdateCpuUsage();
UpdateMemoryUsage();
UpdateDiskUsage();
UpdateNetworkUsage();
UpdateProcessInfo();
UpdateSystemUptime();
}
catch (Exception ex)
{
Debug.WriteLine($"更新系统资源失败: {ex.Message}");
}
}
private void UpdateCpuUsage()
{
try
{
// 方法1: 使用PerformanceCounter
if (_cpuCounter != null)
{
_resourceInfo.CpuUsage = _cpuCounter.NextValue();
}
// 方法2: 使用GetSystemTimes(更精确)
if (GetSystemTimes(out long idleTime, out long kernelTime, out long userTime))
{
long totalTime = kernelTime + userTime;
long idleTimeDiff = idleTime - _prevIdleTime;
long totalTimeDiff = totalTime - (_prevKernelTime + _prevUserTime);
if (_prevIdleTime != 0 && _prevKernelTime != 0 && _prevUserTime != 0)
{
if (totalTimeDiff > 0)
{
float cpuUsage = 100.0f * (1.0f - (float)idleTimeDiff / totalTimeDiff);
_resourceInfo.CpuUsage = Math.Min(Math.Max(cpuUsage, 0), 100);
}
}
_prevIdleTime = idleTime;
_prevKernelTime = kernelTime;
_prevUserTime = userTime;
}
}
catch (Exception ex)
{
Debug.WriteLine($"更新CPU使用率失败: {ex.Message}");
}
}
private void UpdateMemoryUsage()
{
try
{
if (_memoryCounter != null)
{
float availableMB = _memoryCounter.NextValue();
if (_resourceInfo.TotalMemory > 0)
{
_resourceInfo.UsedMemory = _resourceInfo.TotalMemory - (ulong)availableMB;
_resourceInfo.MemoryUsage = (float)_resourceInfo.UsedMemory / _resourceInfo.TotalMemory * 100;
}
}
// 备用方法: 使用WMI
if (_resourceInfo.TotalMemory == 0)
{
using (var searcher = new ManagementObjectSearcher(
"SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem"))
{
foreach (var obj in searcher.Get())
{
if (ulong.TryParse(obj["TotalVisibleMemorySize"]?.ToString(), out ulong totalMemoryKB) &&
ulong.TryParse(obj["FreePhysicalMemory"]?.ToString(), out ulong freeMemoryKB))
{
_resourceInfo.TotalMemory = totalMemoryKB / 1024; // KB to MB
_resourceInfo.UsedMemory = (totalMemoryKB - freeMemoryKB) / 1024;
_resourceInfo.MemoryUsage = (float)_resourceInfo.UsedMemory /
_resourceInfo.TotalMemory * 100;
}
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"更新内存使用率失败: {ex.Message}");
}
}
private void UpdateDiskUsage()
{
try
{
if (_diskReadCounter != null && _diskWriteCounter != null)
{
float readSpeed = _diskReadCounter.NextValue();
float writeSpeed = _diskWriteCounter.NextValue();
// 转换为MB/s
readSpeed /= 1024 * 1024;
writeSpeed /= 1024 * 1024;
// 更新磁盘信息
foreach (var disk in _resourceInfo.DiskInfos)
{
disk.ReadSpeed = readSpeed / _resourceInfo.DiskInfos.Count;
disk.WriteSpeed = writeSpeed / _resourceInfo.DiskInfos.Count;
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"更新磁盘使用率失败: {ex.Message}");
}
}
private void UpdateNetworkUsage()
{
try
{
float totalDownloadSpeed = 0;
float totalUploadSpeed = 0;
for (int i = 0; i < _networkCounters.Count; i += 2)
{
if (i + 1 < _networkCounters.Count)
{
float downloadSpeed = _networkCounters[i].NextValue();
float uploadSpeed = _networkCounters[i + 1].NextValue();
// 转换为KB/s
downloadSpeed /= 1024;
uploadSpeed /= 1024;
totalDownloadSpeed += downloadSpeed;
totalUploadSpeed += uploadSpeed;
}
}
_resourceInfo.NetworkDownloadSpeed = totalDownloadSpeed;
_resourceInfo.NetworkUploadSpeed = totalUploadSpeed;
}
catch (Exception ex)
{
Debug.WriteLine($"更新网络使用率失败: {ex.Message}");
}
}
private void UpdateProcessInfo()
{
try
{
var processList = new List<ProcessInfo>();
var processes = Process.GetProcesses();
foreach (var process in processes.Take(20)) // 限制数量以提高性能
{
try
{
var processInfo = new ProcessInfo
{
ProcessId = process.Id,
ProcessName = process.ProcessName
};
// 获取CPU使用率
if (_processCpuCounters.Any(p => p.InstanceName == process.ProcessName))
{
var counter = _processCpuCounters.FirstOrDefault(p =>
p.InstanceName == process.ProcessName);
if (counter != null)
{
processInfo.CpuPercent = counter.NextValue() /
Environment.ProcessorCount;
}
}
// 获取内存使用
process.Refresh();
processInfo.MemoryMB = process.WorkingSet64 / (1024f * 1024f);
processList.Add(processInfo);
}
catch
{
// 忽略无权限访问的进程
}
}
_resourceInfo.TopProcesses = processList
.OrderByDescending(p => p.CpuPercent)
.Take(10)
.ToList();
}
catch (Exception ex)
{
Debug.WriteLine($"更新进程信息失败: {ex.Message}");
}
}
private void UpdateSystemUptime()
{
try
{
using (var uptime = new PerformanceCounter("System", "System Up Time"))
{
uptime.NextValue(); // 第一次调用初始化
float seconds = uptime.NextValue();
_resourceInfo.SystemUptime = DateTime.Now.AddSeconds(-seconds);
}
}
catch
{
// 备用方法
_resourceInfo.SystemUptime = DateTime.Now - TimeSpan.FromTicks(
Environment.TickCount * TimeSpan.TicksPerMillisecond);
}
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
#region IDisposable
public void Dispose()
{
StopMonitoring();
_cpuCounter?.Dispose();
_memoryCounter?.Dispose();
_diskReadCounter?.Dispose();
_diskWriteCounter?.Dispose();
foreach (var counter in _networkCounters)
counter?.Dispose();
foreach (var counter in _processCpuCounters)
counter?.Dispose();
}
#endregion
}
3.3 ViewModel层
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Timers;
using SystemResouceWpfApp.Models;
using SystemResouceWpfApp.Services;
using Timer = System.Timers.Timer;
namespace SystemResouceWpfApp.ViewModel;
// ViewModels/MainViewModel.cs
public class MainViewModel : INotifyPropertyChanged
{
#region Fields
private readonly SystemMonitorService _monitorService;
private readonly Timer _updateTimer;
private readonly ObservableCollection<ChartDataPoint> _cpuHistory = new ObservableCollection<ChartDataPoint>();
private readonly ObservableCollection<ChartDataPoint> _memoryHistory = new ObservableCollection<ChartDataPoint>();
private readonly ObservableCollection<ChartDataPoint> _networkHistory = new ObservableCollection<ChartDataPoint>();
private const int MAX_HISTORY_POINTS = 60;
#endregion
#region Properties
public SystemResourceInfo ResourceInfo => _monitorService.ResourceInfo;
public ObservableCollection<ChartDataPoint> CpuHistory => _cpuHistory;
public ObservableCollection<ChartDataPoint> MemoryHistory => _memoryHistory;
public ObservableCollection<ChartDataPoint> NetworkHistory => _networkHistory;
private bool _isMonitoring;
public bool IsMonitoring
{
get => _isMonitoring;
set
{
if (_isMonitoring != value)
{
_isMonitoring = value;
OnPropertyChanged();
}
}
}
private DateTime _startTime = DateTime.Now;
public DateTime StartTime
{
get => _startTime;
set
{
if (_startTime != value)
{
_startTime = value;
OnPropertyChanged();
}
}
}
public string UptimeString => GetUptimeString();
#endregion
#region Commands
public RelayCommand StartCommand { get; }
public RelayCommand StopCommand { get; }
public RelayCommand RefreshCommand { get; }
public RelayCommand ExportCommand { get; }
#endregion
#region Constructor
public MainViewModel()
{
_monitorService = SystemMonitorService.Instance;
_monitorService.PropertyChanged += OnMonitorServicePropertyChanged;
_updateTimer = new System.Timers.Timer(1000); // 1秒更新一次
_updateTimer.Elapsed += OnUpdateTimerElapsed;
// 初始化历史数据
InitializeHistoryData();
// 初始化命令
StartCommand = new RelayCommand(StartMonitoring, () => !IsMonitoring);
StopCommand = new RelayCommand(StopMonitoring, () => IsMonitoring);
RefreshCommand = new RelayCommand(RefreshData);
ExportCommand = new RelayCommand(ExportData);
// 开始监控
StartMonitoring();
}
#endregion
#region Private Methods
private void InitializeHistoryData()
{
for (int i = 0; i < MAX_HISTORY_POINTS; i++)
{
var time = DateTime.Now.AddSeconds(-(MAX_HISTORY_POINTS - i));
_cpuHistory.Add(new ChartDataPoint { Time = time, Value = 0 });
_memoryHistory.Add(new ChartDataPoint { Time = time, Value = 0 });
_networkHistory.Add(new ChartDataPoint { Time = time, Value = 0 });
}
}
private void UpdateHistoryData()
{
var now = DateTime.Now;
// 更新CPU历史
_cpuHistory.Add(new ChartDataPoint
{
Time = now,
Value = ResourceInfo.CpuUsage
});
if (_cpuHistory.Count > MAX_HISTORY_POINTS)
_cpuHistory.RemoveAt(0);
// 更新内存历史
_memoryHistory.Add(new ChartDataPoint
{
Time = now,
Value = ResourceInfo.MemoryUsage
});
if (_memoryHistory.Count > MAX_HISTORY_POINTS)
_memoryHistory.RemoveAt(0);
// 更新网络历史(下载速度)
_networkHistory.Add(new ChartDataPoint
{
Time = now,
Value = ResourceInfo.NetworkDownloadSpeed
});
if (_networkHistory.Count > MAX_HISTORY_POINTS)
_networkHistory.RemoveAt(0);
}
private string GetUptimeString()
{
var uptime = DateTime.Now - ResourceInfo.SystemUptime;
return $"{uptime.Days}d {uptime.Hours}h {uptime.Minutes}m {uptime.Seconds}s";
}
private void OnMonitorServicePropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(SystemMonitorService.IsMonitoring))
{
IsMonitoring = _monitorService.IsMonitoring;
}
}
private void OnUpdateTimerElapsed(object sender, ElapsedEventArgs e)
{
UpdateHistoryData();
OnPropertyChanged(nameof(UptimeString));
}
#endregion
#region Command Methods
private void StartMonitoring()
{
_monitorService.StartMonitoring();
_updateTimer.Start();
StartTime = DateTime.Now;
}
private void StopMonitoring()
{
_updateTimer.Stop();
_monitorService.StopMonitoring();
}
private void RefreshData()
{
_monitorService.GetCurrentStatus();
}
private void ExportData()
{
// 导出数据逻辑
// 这里可以实现导出为CSV、JSON等格式
}
#endregion
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
public class ChartDataPoint
{
public DateTime Time { get; set; }
public double Value { get; set; }
}
public class RelayCommand : System.Windows.Input.ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public event EventHandler CanExecuteChanged
{
add { System.Windows.Input.CommandManager.RequerySuggested += value; }
remove { System.Windows.Input.CommandManager.RequerySuggested -= value; }
}
public RelayCommand(Action execute, Func<bool> canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;
public void Execute(object parameter) => _execute();
}
3.4 WPF界面实现
<Window
x:Class="SystemResouceWpfApp.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:local="clr-namespace:SystemResouceWpfApp"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="系统资源监控仪表盘"
Width="1600"
Height="900"
Background="#0F0F23"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<Window.Resources>
<!-- 颜色资源 -->
<Color x:Key="PrimaryColor">#2196F3</Color>
<Color x:Key="SuccessColor">#4CAF50</Color>
<Color x:Key="WarningColor">#FF9800</Color>
<Color x:Key="DangerColor">#F44336</Color>
<Color x:Key="InfoColor">#00BCD4</Color>
<Color x:Key="DarkColor">#121212</Color>
<Color x:Key="LightColor">#F5F5F5</Color>
<!-- 渐变画刷 -->
<LinearGradientBrush x:Key="PrimaryGradient" StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0" Color="#2196F3" />
<GradientStop Offset="1" Color="#1976D2" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="SuccessGradient" StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0" Color="#4CAF50" />
<GradientStop Offset="1" Color="#388E3C" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="WarningGradient" StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0" Color="#FF9800" />
<GradientStop Offset="1" Color="#F57C00" />
</LinearGradientBrush>
<!-- 样式 -->
<Style x:Key="MetricCardStyle" TargetType="Border">
<Setter Property="Background" Value="#1E1E2E" />
<Setter Property="CornerRadius" Value="12" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="#2D2D3D" />
<Setter Property="Padding" Value="20" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect
BlurRadius="20"
Opacity="0.3"
ShadowDepth="0" />
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MetricTitleStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="#AAAAAA" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Margin" Value="0,0,0,8" />
</Style>
<Style x:Key="MetricValueStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="32" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style x:Key="MetricUnitStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="#888888" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Margin" Value="4,0,0,0" />
</Style>
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="Background" Value="#2D2D3D" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="12,8" />
<Setter Property="Margin" Value="4" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
Background="{TemplateBinding Background}"
BorderBrush="#3D3D4D"
BorderThickness="1"
CornerRadius="6">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#3D3D4D" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#4D4D5D" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<!-- 背景 -->
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0" Color="#0F0F23" />
<GradientStop Offset="1" Color="#1A1A2E" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<!-- 主布局 -->
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- 标题栏 -->
<Border
Grid.Row="0"
Padding="0,0,0,20"
Background="Transparent">
<StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal">
<StackPanel>
<TextBlock
FontSize="28"
FontWeight="Bold"
Foreground="White"
Text="🚀 系统资源监控仪表盘" />
<TextBlock
Margin="0,4,0,0"
FontSize="14"
Foreground="#888888"
Text="实时监控系统性能指标" />
</StackPanel>
<StackPanel
Margin="20,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Orientation="Horizontal">
<Button
Command="{Binding StartCommand}"
Content="▶ 开始监控"
Style="{StaticResource ButtonStyle}" />
<Button
Command="{Binding StopCommand}"
Content="⏸ 暂停监控"
Style="{StaticResource ButtonStyle}" />
<Button
Command="{Binding RefreshCommand}"
Content="🔄 刷新"
Style="{StaticResource ButtonStyle}" />
<Button
Command="{Binding ExportCommand}"
Content="📤 导出数据"
Style="{StaticResource ButtonStyle}" />
</StackPanel>
</StackPanel>
</Border>
<!-- 监控数据区域 -->
<ScrollViewer
Grid.Row="1"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- 第一行:核心指标 -->
<StackPanel Grid.Row="0" Orientation="Horizontal">
<!-- CPU监控卡片 -->
<Border
Width="300"
Margin="0,0,20,20"
Style="{StaticResource MetricCardStyle}">
<StackPanel>
<TextBlock Style="{StaticResource MetricTitleStyle}" Text="CPU使用率" />
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
<TextBlock Style="{StaticResource MetricValueStyle}" Text="{Binding ResourceInfo.CpuUsage, StringFormat={}{0:F1}}" />
<TextBlock
Margin="0,0,0,8"
VerticalAlignment="Bottom"
Style="{StaticResource MetricUnitStyle}"
Text="%" />
</StackPanel>
<!-- CPU进度条 -->
<Border
Height="12"
Margin="0,12,0,0"
Background="#2D2D3D"
CornerRadius="6">
<Border Width="{Binding ResourceInfo.CpuUsage}" HorizontalAlignment="Left">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="#4CAF50" />
<GradientStop Offset="0.7" Color="#FF9800" />
<GradientStop Offset="1" Color="#F44336" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Border>
<TextBlock
Margin="0,8,0,0"
Foreground="#888888"
Text="{Binding ResourceInfo.CpuUsage, StringFormat={}核心数: {0:F0}}" />
</StackPanel>
</Border>
<!-- 内存监控卡片 -->
<Border
Width="300"
Margin="0,0,20,20"
Style="{StaticResource MetricCardStyle}">
<StackPanel>
<TextBlock Style="{StaticResource MetricTitleStyle}" Text="内存使用" />
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
<TextBlock Style="{StaticResource MetricValueStyle}" Text="{Binding ResourceInfo.MemoryUsage, StringFormat={}{0:F1}}" />
<TextBlock
Margin="0,0,0,8"
VerticalAlignment="Bottom"
Style="{StaticResource MetricUnitStyle}"
Text="%" />
</StackPanel>
<!-- 内存进度条 -->
<Border
Height="12"
Margin="0,12,0,0"
Background="#2D2D3D"
CornerRadius="6">
<Border Width="{Binding ResourceInfo.MemoryUsage}" HorizontalAlignment="Left">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="#2196F3" />
<GradientStop Offset="1" Color="#1976D2" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Border>
<TextBlock
Margin="0,8,0,0"
Foreground="#888888"
Text="{Binding ResourceInfo.UsedMemory, StringFormat={}已用: {0} MB / {1} MB}" />
</StackPanel>
</Border>
<!-- 网络监控卡片 -->
<Border
Width="300"
Margin="0,0,20,20"
Style="{StaticResource MetricCardStyle}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock Style="{StaticResource MetricTitleStyle}" Text="网络活动" />
<StackPanel Orientation="Horizontal">
<StackPanel Margin="0,0,20,0">
<TextBlock
FontSize="12"
Foreground="#888888"
Text="上传" />
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
<TextBlock
FontSize="24"
Style="{StaticResource MetricValueStyle}"
Text="{Binding ResourceInfo.NetworkUploadSpeed, StringFormat={}{0:F1}}" />
<TextBlock
FontSize="12"
Style="{StaticResource MetricUnitStyle}"
Text="KB/s" />
</StackPanel>
</StackPanel>
<StackPanel>
<TextBlock
FontSize="12"
Foreground="#888888"
Text="下载" />
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
<TextBlock
FontSize="24"
Style="{StaticResource MetricValueStyle}"
Text="{Binding ResourceInfo.NetworkDownloadSpeed, StringFormat={}{0:F1}}" />
<TextBlock
FontSize="12"
Style="{StaticResource MetricUnitStyle}"
Text="KB/s" />
</StackPanel>
</StackPanel>
</StackPanel>
</StackPanel>
<!-- 网络图标 -->
<Viewbox
Grid.Row="1"
Width="80"
Height="80"
HorizontalAlignment="Right"
VerticalAlignment="Bottom">
<Canvas Width="100" Height="100">
<!-- 网络波动图形 -->
<Path
Data="M 0,50 Q 25,30 50,50 T 100,50"
Stroke="#2196F3"
StrokeDashArray="5,2"
StrokeThickness="2" />
<Path
Data="M 0,60 Q 25,40 50,60 T 100,60"
Stroke="#4CAF50"
StrokeThickness="2" />
</Canvas>
</Viewbox>
</Grid>
</Border>
<!-- 系统运行时间卡片 -->
<Border
Width="300"
Margin="0,0,0,20"
Style="{StaticResource MetricCardStyle}">
<StackPanel>
<TextBlock Style="{StaticResource MetricTitleStyle}" Text="系统运行时间" />
<TextBlock
FontSize="24"
Style="{StaticResource MetricValueStyle}"
Text="{Binding UptimeString}" />
<TextBlock
Margin="0,8,0,0"
Foreground="#888888"
Text="{Binding ResourceInfo.SystemUptime, StringFormat={}启动时间: {0:yyyy-MM-dd HH:mm:ss}}" />
<!-- 运行时间图标 -->
<Viewbox
Width="60"
Height="60"
Margin="0,12,0,0"
HorizontalAlignment="Left">
<Canvas Width="100" Height="100">
<Ellipse
Width="80"
Height="80"
Stroke="#FF9800"
StrokeDashArray="314"
StrokeDashOffset="100"
StrokeThickness="8">
<Ellipse.RenderTransform>
<RotateTransform Angle="90" CenterX="40" CenterY="40" />
</Ellipse.RenderTransform>
</Ellipse>
<TextBlock
Margin="30,30,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="40"
Text="⏱" />
</Canvas>
</Viewbox>
</StackPanel>
</Border>
</StackPanel>
<!-- 第二行:历史图表 -->
<Border
Grid.Row="1"
Margin="0,0,0,20"
Style="{StaticResource MetricCardStyle}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Style="{StaticResource MetricTitleStyle}" Text="历史趋势" />
<!-- 使用LiveCharts图表 -->
<lvc:CartesianChart
Grid.Row="1"
Margin="0,20,0,0"
LegendLocation="Right"
Series="{Binding ChartSeries}">
<lvc:CartesianChart.AxisX>
<lvc:Axis Title="时间" LabelFormatter="{Binding DateTimeFormatter}" />
</lvc:CartesianChart.AxisX>
<lvc:CartesianChart.AxisY>
<lvc:Axis
Title="使用率 (%)"
MaxValue="100"
MinValue="0" />
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
</Grid>
</Border>
<!-- 第三行:磁盘和进程信息 -->
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- 磁盘信息 -->
<Border
Grid.Column="0"
Margin="0,0,10,0"
Style="{StaticResource MetricCardStyle}">
<StackPanel>
<TextBlock Style="{StaticResource MetricTitleStyle}" Text="磁盘使用情况" />
<ItemsControl Margin="0,10,0,0" ItemsSource="{Binding ResourceInfo.DiskInfos}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border
Margin="0,0,0,8"
Padding="12"
Background="#2D2D3D"
CornerRadius="6">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- 磁盘名称和容量 -->
<StackPanel
Grid.Row="0"
HorizontalAlignment="Center"
Orientation="Horizontal">
<TextBlock
FontWeight="Bold"
Foreground="White"
Text="{Binding DriveLetter}" />
<TextBlock
Margin="8,0,0,0"
Foreground="#888888"
Text="{Binding DriveName}" />
<TextBlock
HorizontalAlignment="Right"
Foreground="#888888"
Text="{Binding TotalSizeGB, StringFormat={}{0} GB}" />
</StackPanel>
<!-- 磁盘使用率 -->
<Border
Grid.Row="1"
Height="8"
Margin="0,8,0,4"
Background="#3D3D4D"
CornerRadius="4">
<Border Width="{Binding UsagePercent}" HorizontalAlignment="Left">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="#4CAF50" />
<GradientStop Offset="0.7" Color="#FF9800" />
<GradientStop Offset="1" Color="#F44336" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Border>
<!-- 磁盘读写速度 -->
<StackPanel
Grid.Row="2"
HorizontalAlignment="Center"
Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="0,0,4,0"
Foreground="#2196F3"
Text="📥" />
<TextBlock
FontSize="12"
Foreground="#888888"
Text="{Binding ReadSpeed, StringFormat={}{0:F1} MB/s}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="0,0,4,0"
Foreground="#FF9800"
Text="📤" />
<TextBlock
FontSize="12"
Foreground="#888888"
Text="{Binding WriteSpeed, StringFormat={}{0:F1} MB/s}" />
</StackPanel>
<TextBlock
FontSize="12"
Foreground="#888888"
Text="{Binding UsagePercent, StringFormat={}{0:F1}% 已用}" />
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
<!-- 进程信息 -->
<Border
Grid.Column="1"
Margin="10,0,0,0"
Style="{StaticResource MetricCardStyle}">
<StackPanel>
<TextBlock Style="{StaticResource MetricTitleStyle}" Text="进程监控" />
<!-- 进程列表 -->
<DataGrid
Margin="0,10,0,0"
AutoGenerateColumns="False"
Background="Transparent"
BorderThickness="0"
HeadersVisibility="Column"
ItemsSource="{Binding ResourceInfo.TopProcesses}"
RowBackground="Transparent">
<DataGrid.Columns>
<DataGridTextColumn
Width="*"
Binding="{Binding ProcessName}"
Foreground="White"
Header="进程名" />
<DataGridTextColumn
Width="80"
Binding="{Binding ProcessId}"
Foreground="#888888"
Header="PID" />
<DataGridTemplateColumn Width="120" Header="CPU">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Border
Height="6"
VerticalAlignment="Center"
Background="#2D2D3D"
CornerRadius="3">
<Border Width="{Binding CpuPercent}" HorizontalAlignment="Left">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="#4CAF50" />
<GradientStop Offset="0.7" Color="#FF9800" />
<GradientStop Offset="1" Color="#F44336" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Border>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="10"
Foreground="White"
Text="{Binding CpuPercent, StringFormat={}{0:F1}%}" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
Width="100"
Binding="{Binding MemoryMB, StringFormat={}{0:F1} MB}"
Foreground="#888888"
Header="内存" />
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Border>
</Grid>
</Grid>
</ScrollViewer>
<!-- 状态栏 -->
<Border
Grid.Row="2"
Height="40"
Margin="0,20,0,0"
Background="#1A1A2E"
CornerRadius="6">
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<Ellipse
Width="8"
Height="8"
Margin="0,0,8,0"
Fill="#4CAF50">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Style.Triggers>
<DataTrigger Binding="{Binding IsMonitoring}" Value="True">
<Setter Property="Fill" Value="#4CAF50" />
</DataTrigger>
<DataTrigger Binding="{Binding IsMonitoring}" Value="False">
<Setter Property="Fill" Value="#F44336" />
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<TextBlock Foreground="#888888" Text="{Binding IsMonitoring}" />
<TextBlock
Margin="20,0,0,0"
Foreground="#666666"
Text=" | 最后更新: " />
<TextBlock Foreground="#888888" Text="{Binding StartTime, StringFormat={}HH:mm:ss}" />
</StackPanel>
</Border>
</Grid>
</Grid>
</Window>using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SystemResouceWpfApp.ViewModel;
namespace SystemResouceWpfApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
}运行效果:

本文详细介绍了如何使用WPF创建一个功能完整的系统资源监控工具,包括:
- 核心功能:CPU、内存、磁盘、网络监控
- MVVM架构:清晰的代码分离和可测试性
- 美观UI:现代化设计,实时数据可视化
- 扩展性:易于添加新监控项和功能
- 部署方案:单文件发布,便于分发
这个监控工具具有以下特点:
- 实时监控系统资源使用情况
- 美观的数据可视化界面
- 历史趋势图表
- 进程和磁盘详细监控
- 可扩展的报警系统
- 易于部署和更新
通过这个项目,您不仅学习了WPF的高级应用,还掌握了系统编程、性能监控和现代UI设计的最佳实践。您可以根据需要进一步扩展功能,如添加GPU监控、温度监控、日志记录等功能。
以上就是利用WPF实现系统资源监控的完整代码的详细内容,更多关于WPF系统资源监控的资料请关注脚本之家其它相关文章!
