项目中需要获取磁盘的使用情况,判断磁盘是否处于忙碌状态。由于之前有了获取cpu使用率的经验,所以这次依然打算使用PerformanceCounter来获取磁盘状态的。
PerformanceCounter顾名思义就是获取性能计数器的读数,但网上大多数都是用来获取cpu的使用率情况的(其实他们获取的并不准😁,准确的获取方式参见上面的链接),没有获取磁盘的,故需要来调用api来查找结果。
PerformanceCounter的定义为:
public PerformanceCounter(string categoryName, string counterName, string instanceName);
我们如果要使用PerformanceCounter,就必须知道categoryName、counterName和instanceName三个传参,好在可以通过api的方式来获取参数:
1.获取所有计数器的CategoryName
首先是要获取所有计数器的CategoryName,以下是获取代码,所有的CategoryName见文章尾:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PerformanceCounterFun
{
class Program
{
static void Main(string[] args)
{
PerformanceCounterCategory[] pcc = PerformanceCounterCategory.GetCategories();
for (int i = 0; i < pcc.Length; i++)
{
Console.WriteLine(pcc[i].CategoryName);
}
Console.ReadLine();
}
}
}
执行后的部分结果:

注:GetCategories()为检索本地计算机已注册的性能计数器类别的列表。所以本地调试还是自己获取下比较好。
然后需要来排查确定是哪个CategoryName,我本次打算做磁盘相关的,所以就搜disk,以下是结果:

缩小了范围后,发现 LogicalDisk和PhysicalDisk比较接近,然后在网上搜索后发现PhysicalDisk比较符合需要,经过验证后确认,LogicalDisk是按照逻辑磁盘来划分,而PhysicalDisk是通过物理磁盘来划分,举个例子,如果一个硬盘分区成C,D两个盘符,LogicalDisk是C,D盘分别进行统计性能的,而PhysicalDisk则C,D盘符同时统计,故PhysicalDisk比较符合本次需求。
2.获取instanceName
然后就是查询其instanceName,代码如下:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PerformanceCounterFun
{
class Program
{
static void Main(string[] args)
{
PerformanceCounterCategory diskCounter = new PerformanceCounterCategory("PhysicalDisk");
string[] instanceNames = diskCounter.GetInstanceNames();
for (int i = 0; i < instanceNames.Length; i++)
{
Console.WriteLine(instanceNames[i]);
}
Console.ReadLine();
}
}
}
执行结果:

由于我电脑插入了优盘,故这里找到了3个参数,其中 0 C: D:是我的磁盘,1 E:是优盘,跟资源管理器上面显示的一致。
3.获取CounterName
然后就是查询其CounterName,代码如下:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PerformanceCounterFun
{
class Program
{
static void Main(string[] args)
{
PerformanceCounterCategory diskCounter = new PerformanceCounterCategory("PhysicalDisk");
PerformanceCounter[] counterName = diskCounter.GetCounters("0 C: D:");
for (int i = 0; i < counterName.Length; i++)
{
Console.WriteLine(counterName[i].CounterName);
}
Console.ReadLine();
}
}
}
执行结果:
Current Disk Queue Length
% Disk Time
Avg. Disk Queue Length
% Disk Read Time
Avg. Disk Read Queue Length
% Disk Write Time
Avg. Disk Write Queue Length
Avg. Disk sec/Transfer
Avg. Disk sec/Read
Avg. Disk sec/Write
Disk Transfers/sec
Disk Reads/sec
Disk Writes/sec
Disk Bytes/sec
Disk Read Bytes/sec
Disk Write Bytes/sec
Avg. Disk Bytes/Transfer
Avg. Disk Bytes/Read
Avg. Disk Bytes/Write
% Idle Time
Split IO/Sec
经过一番测试,发现% Idle Time这个参数比较合适,以下是代码和执行结果:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PerformanceCounterFun
{
class Program
{
static void Main(string[] args)
{
PerformanceCounter diskInfo = new PerformanceCounter("PhysicalDisk", "% Idle Time", "0 C: D:");
while (true)
{
float diskCounter = diskInfo.NextValue();
Console.WriteLine(diskCounter);
Thread.Sleep(1000);
}
}
}
}

可以看到,这个"% Idle Time"参数为磁盘的空闲时间,拿100减去它就是任务管理器里的磁盘活动时间,至此,可以交差了。
4.题外话
不过在尝试过程中,发现了一个有趣的参数:Avg. Disk Queue Length。其字面意思就是磁盘队列平均长度,我找了台还在使用机械硬盘的老爷机跑了一下,发现其队列长度达到1以上后,其任务管理器里的磁盘活动时间就会变成100%,故猜测这个参数跟这个磁盘活动时间是有关联的。
磁盘队列平均长度应该是统计一段内的磁盘队列平均共有多少个待处理的磁盘任务每秒,如果磁盘性能较差,那有可能在运行大量使用磁盘io的软件(比如360杀毒软件全盘扫描和瑞星杀毒全盘扫描同时开)时,会堆积大量的磁盘任务,导致严重拖慢系统响应速度。而这个队列平均长度大于1,说明磁盘时刻都有磁盘任务要处理,故磁盘活动时间就是100%。
但是这个磁盘活动时间并不能完全体现磁盘的使用情况,因为磁盘队列平均长度达到1以后,就是100%了,而在实际使用过程中,磁盘队列平均长度可以达到2,300,甚至更高,这个时候系统已经接近假死了,故磁盘队列平均长度更能体现磁盘的使用情况。但由于某种原因,我们还是选择了磁盘空闲时间来作为磁盘的性能体现。
以下是在ssd上跑的Avg. Disk Queue Length,凑合看,老爷机已经假死了,没办法录屏:

5.附录
附录--本机所有的计数器:
| ServiceModelOperation 3.0.0.0 |
| Microsoft FTP Service |
| Database ==> Instances |
| Storage Spaces Tier |
| ASP.NET Applications |
| GPU Process Memory |
| Process |
| LogicalDisk |
| XHCI Interrupter |
| SMB Direct Connection |
| Hyper-V Dynamic Memory Balancer |
| WSMan Quota Statistics |
| RemoteFX Root GPU Management |
| Storage QoS Filter - Flow |
| Network Adapter |
| Hyper-V VM Live Migration |
| WinNAT ICMP |
| Hyper-V Virtual Switch Port |
| Telephony |
| WinNAT |
| NBT Connection |
| RAS Total |
| WinNAT UDP |
| UDPv4 |
| Distributed Routing Table |
| UDPv6 |
| ASP.NET |
| Hyper-V Hypervisor Virtual Processor |
| RAS |
| Hyper-V Virtual Storage Device |
| Objects |
| .NET Memory Cache 4.0 |
| NUMA Node Memory |
| IPsec AuthIP IPv6 |
| ServiceModelEndpoint 3.0.0.0 |
| ASP.NET v2.0.50727 |
| IPsec AuthIP IPv4 |
| Hyper-V Hypervisor Root Partition |
| Hyper-V Virtual SMB |
| Hyper-V Virtual Machine Bus |
| Teredo Relay |
| Terminal Services Session |
| .NET Data Provider for Oracle |
| .NET CLR Loading |
| Hyper-V VM Vid Partition |
| .NET CLR LocksAndThreads |
| Hyper-V Hypervisor |
| PacketDirect Receive Counters |
| Redirector |
| Hyper-V Virtual Network Adapter Drop Reasons |
| Hyper-V VM Remoting |
| GPU Non Local Adapter Memory |
| ServiceModelEndpoint 4.0.0.0 |
| ICMPv6 |
| ASP.NET State Service |
| .NET CLR Exceptions |
| XHCI CommonBuffer |
| Power Meter |
| Web Service Cache |
| .NET CLR Remoting |
| Energy Meter |
| Pacer Pipe |
| RemoteFX Network |
| HTTP Service |
| Hyper-V Virtual Machine Health Summary |
| SMB Server |
| Job Object Details |
| Offline Files |
| PacketDirect Receive Filters |
| Thermal Zone Information |
| Bluetooth Device |
| ServiceModelService 3.0.0.0 |
| WinNAT TCP |
| Event Tracing for Windows Session |
| PhysicalDisk |
| TCPIP Performance Diagnostics (Per-CPU) |
| System |
| Hyper-V Legacy Network Adapter |
| Network Interface |
| Storage Spaces Drt |
| Hyper-V Worker Virtual Processor |
| Per Processor Network Interface Card Activity |
| VFP Port Average Outbound Network Traffic |
| Hyper-V Virtual Machine Bus Provider Pipes |
| Hyper-V Virtual Network Adapter |
| .NET Data Provider for SqlServer |
| Hyper-V VM IO APIC |
| Browser |
| Database ==> TableClasses |
| IPHTTPS Global |
| VFP QoS Queue Average Outbound Network Traffic |
| VFP Port Total Inbound Network Traffic |
| SMSvcHost 3.0.0.0 |
| GPU Local Adapter Memory |
| .NET CLR Security |
| ServiceModelService 4.0.0.0 |
| Terminal Services |
| RemoteFX Graphics |
| ReFS |
| WFP |
| Event Tracing for Windows |
| VFP QoS Queue Total Outbound Network Traffic |
| USB |
| Hyper-V Virtual Network Adapter VRSS |
| WFP Classify |
| VFP Port Total Inbound Dropped Network Packets |
| Windows Workflow Foundation |
| VFP Port Total Outbound Dropped Network Packets |
| MSDTC Bridge 4.0.0.0 |
| IPsec IKEv2 IPv6 |
| .NET CLR Networking |
| DNS64 Global |
| WorkflowServiceHost 4.0.0.0 |
| Per Processor Network Activity Cycles |
| ASP.NET v4.0.30319 |
| TCPv6 |
| Hyper-V VM Virtual Device Pipe IO |
| TCPv4 |
| VFP QoS Queue Total Inbound Network Traffic |
| Client Side Caching |
| Hyper-V Dynamic Memory Integration Service |
| IPHTTPS Session |
| VFP QoS Queue Average Inbound Network Traffic |
| Teredo Server |
| IPsec IKEv2 IPv4 |
| Search Indexer |
| WFPv4 |
| Storage Spaces Virtual Disk |
| WFPv6 |
| PacketDirect EC Utilization |
| Distributed Transaction Coordinator |
| HTTP Service Url Groups |
| Fax Service |
| .NET CLR Networking 4.0.0.0 |
| IPv6 |
| Microsoft Winsock BSP |
| WF (System.Workflow) 4.0.0.0 |
| IPsec IKEv1 IPv6 |
| Network QoS Policy |
| IPsec IKEv1 IPv4 |
| Hyper-V Virtual IDE Controller (Emulated) |
| Event Log |
| Netlogon |
| .NET CLR Memory |
| Hyper-V Virtual Machine Bus Pipes |
| Cache |
| Peer Name Resolution Protocol |
| XHCI TransferRing |
| Windows Media Player Metadata |
| Storage Spaces Write Cache |
| Synchronization |
| ASP.NET Apps v2.0.50727 |
| PowerShell Workflow |
| Hyper-V Dynamic Memory VM |
| Generic IKEv1, AuthIP, and IKEv2 |
| Memory |
| Authorization Manager Applications |
| Hyper-V VM Save, Snapshot, and Restore |
| Print Queue |
| IPsec Driver |
| SMSvcHost 4.0.0.0 |
| SMB Server Shares |
| Hyper-V VM Worker Process Memory Manager |
| Database |
| IPsec Connections |
| Windows Time Service |
| SMB Server Sessions |
| Database ==> Databases |
| Hyper-V Virtual Switch |
| TCPIP Performance Diagnostics |
| Physical Network Interface Card Activity |
| HTTP Service Request Queues |
| Processor Information |
| Paging File |
| Hyper-V Virtual Switch Processor |
| Processor |
| MSDTC Bridge 3.0.0.0 |
| RAS Port |
| Thread |
| IPv4 |
| .NET CLR Data |
| VFP Port Total Outbound Network Traffic |
| WFP Reauthorization |
| Teredo Client |
| Pacer Flow |
| BranchCache |
| GPU Engine |
| SynchronizationNuma |
| AppV Client Streamed Data Percentage |
| FileSystem Disk Activity |
| Hyper-V Hypervisor Partition |
| .NET CLR Jit |
| BitLocker |
| Bluetooth Radio |
| Hyper-V VM Vid Driver |
| PacketDirect Queue Depth |
| Storage Management WSP Spaces Runtime |
| W3SVC_W3WP |
| ServiceModelOperation 4.0.0.0 |
| GPU Adapter Memory |
| WinNAT Instance |
| Hyper-V Replica VM |
| PacketDirect Transmit Counters |
| APP_POOL_WAS |
| Hyper-V VM Vid Numa Node |
| .NET CLR Interop |
| ASP.NET Apps v4.0.30319 |
| WAS_W3WP |
| Hyper-V Hypervisor Root Virtual Processor |
| ICMP |
| Web Service |
| Hyper-V Configuration |
| VFP Port Average Inbound Network Traffic |
| Hyper-V Hypervisor Logical Processor |
| Storage QoS Filter - Volume |

本文介绍了如何利用C#的PerformanceCounter类来获取磁盘使用情况,特别是通过PhysicalDisk类别和%IdleTime计数器来判断磁盘是否忙碌。通过获取CategoryName、CounterName和InstanceName,最终实现对磁盘空闲时间的实时监控,从而推算出磁盘活动时间。此外,还探讨了Avg.DiskQueueLength参数对于磁盘使用情况的指示作用。
1555

被折叠的 条评论
为什么被折叠?



