Используя класс System.Diagnostics.PerformanceCounter
, присоедините счетчик PhysicalDisk, связанный с индексируемым диском.
Ниже приведен некоторый код для иллюстрации, хотя в настоящее время он жестко запрограммирован на диске "C:".Вы захотите изменить «C:» на тот, который сканирует ваш процесс.(Это примерный пример кода, который иллюстрирует существование счетчиков производительности - не воспринимайте его как предоставление точной информации - всегда следует использовать только в качестве ориентира. Изменения для собственных целей)
Соблюдайте % Idle Time счетчик, который показывает, как часто привод делает что-либо. 0% idle означает, что диск занят, но не обязательно означает, что он неактивен и не может передавать больше данных.
Объедините % Idle Time с Текущая длина очереди диска , и это сообщит вам, если накопитель становится настолько занятым, что не может обслуживать все запросы данных .Как правило, значение, превышающее 0, означает, что накопитель, вероятно, полностью занят, а значение, превышающее 2, означает, что накопитель полностью насыщен.Эти правила применимы как к SSD, так и к HDD.
Кроме того, любое прочитанное вами значение является мгновенным значением в определенный момент времени.Вы должны выполнить скользящее среднее по нескольким результатам, например, принять показания каждые 100 мс и в среднем 5 показаний, прежде чем использовать информацию из результата для принятия решения (т. Е. Дождаться, пока счетчики не сработают, прежде чем делать ваш следующий запрос ввода-вывода).
internal DiskUsageMonitor(string driveName)
{
// Get a list of the counters and look for "C:"
var perfCategory = new PerformanceCounterCategory("PhysicalDisk");
string[] instanceNames = perfCategory.GetInstanceNames();
foreach (string name in instanceNames)
{
if (name.IndexOf("C:") > 0)
{
if (string.IsNullOrEmpty(driveName))
driveName = name;
}
}
_readBytesCounter = new PerformanceCounter("PhysicalDisk",
"Disk Read Bytes/sec",
driveName);
_writeBytesCounter = new PerformanceCounter("PhysicalDisk",
"Disk Write Bytes/sec",
driveName);
_diskQueueCounter = new PerformanceCounter("PhysicalDisk",
"Current Disk Queue Length",
driveName);
_idleCounter = new PerformanceCounter("PhysicalDisk",
"% Idle Time",
driveName);
InitTimer();
}
internal event DiskUsageResultHander DiskUsageResult;
private void InitTimer()
{
StopTimer();
_perfTimer = new Timer(_updateResolutionMillisecs);
_perfTimer.Elapsed += PerfTimerElapsed;
_perfTimer.Start();
}
private void PerfTimerElapsed(object sender, ElapsedEventArgs e)
{
float diskReads = _readBytesCounter.NextValue();
float diskWrites = _writeBytesCounter.NextValue();
float diskQueue = _diskQueueCounter.NextValue();
float idlePercent = _idleCounter.NextValue();
if (idlePercent > 100)
{
idlePercent = 100;
}
if (DiskUsageResult != null)
{
var stats = new DiskUsageStats
{
DriveName = _readBytesCounter.InstanceName,
DiskQueueLength = (int)diskQueue,
ReadBytesPerSec = (int)diskReads,
WriteBytesPerSec = (int)diskWrites,
DiskUsagePercent = 100 - (int)idlePercent
};
DiskUsageResult(stats);
}
}