Есть ли способ получить время простоя физического диска без ожидания в 1 секунду, необходимого для функции PerformanceCoC#

Место общения программистов C#
Ответить
Anonymous
 Есть ли способ получить время простоя физического диска без ожидания в 1 секунду, необходимого для функции PerformanceCo

Сообщение Anonymous »

Я пытаюсь разработать удобную для пользователя программу, которая не блокирует физический диск при 100% использовании (поэтому даже вход в «Мой компьютер» занимает около 10 секунд).
Моя программа вычисляет хэш для многих (180 тысяч) небольших файлов на диске в несколько потоков. Мое решение состоит в том, чтобы измерить время простоя физического диска в каждом потоке перед чтением следующего файла и решить, следует ли ему Thread.Sleep(100) (сейчас использование диска слишком велико) или вычислить хэш файла (сейчас использование диска достаточно низкое).
Проблема в том, что измерение времени простоя физического диска занимает около 1 секунды, чтобы быть правильным.

Код: Выделить всё

public static float GetPhysicalDiskIdleTime(string physical_disk_instance_name)
{
using (PerformanceCounter disk_idle_time_counter = new PerformanceCounter("PhysicalDisk", "% Idle Time", physical_disk_instance_name/*0 C: D:*/))
{
float first_value = disk_idle_time_counter.NextValue(); //Get the first sample (usually zero, don't know why)
Thread.Sleep(1000); //Wait for a second to get a meaningful sample
float disk_idle_time_percentage = disk_idle_time_counter.NextValue(); //This time it's normal value

return disk_idle_time_percentage;
}
}

случай 1 - И если я вызываю эту функцию перед каждым решением обрабатывать следующий файл или нет, все работает очень медленно (почти нулевое использование процессора и диска) (конечно, для определения времени простоя требуется 1 секунда ожидания).

Код: Выделить всё

static private void ProcessQueue(object this_thread_doesnt_care_about_disk_usage) //this function executes in multiple threads
{
retry_dequeue:
if (this_thread_doesnt_care_about_disk_usage != null)
while (Entries2Check.Count > 0 && CF.GetPhysicalDiskIdleTime(PSO2PhysicalDisk)  0 && this.CurrentPhysicalDiskIdleTime  0)
goto retry_dequeue;
}
случай 2 — я пытался использовать общую переменную в нескольких потоках вместо вызова CF.GetPhysicalDiskIdleTime внутри, картина загрузки стала лучше, но использование все равно часто падает примерно до 50%. Я понимаю, почему это происходит, все вращается с ожиданием около 1 секунды в GetPhysicalDiskIdleTime.
Изображение

Я нарисовал красную линию на графике загрузки — это ожидаемое использование диска.
Изображение

Итак... Есть ли более быстрый способ определить время простоя физического диска? Или есть способ использовать то, что у меня есть, и при этом стабильно использовать диск на 95%?
P.S. если вы не понимаете, почему я делаю это в несколько потоков — вычисление хеша занимает процессорное время, и когда это происходит, активность диска падает. Хочу иметь достойную нагрузку на диск, чтобы как можно быстрее завершить проверку файлов (уже 4 часа занимает).

Подробнее здесь: https://stackoverflow.com/questions/798 ... needed-for
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»