Ответ 1
Используя класс 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);
}
}