Мы создали приложение мониторинга для нашего корпоративного приложения, которое будет контролировать наши приложения. Счетчики производительности. Мы контролируем пару системных счетчиков (память, процессор) и около 10 собственных пользовательских счетчиков производительности. У нас есть 7 или 8 exes, которые мы контролируем, поэтому каждые пару секунд мы проверяем 80 счетчиков.Высокий процессор при использовании PerformanceCounter.NextValue
Все работает отлично, за исключением случаев, когда мы перебираем счетчики, процессор получает удар, 15% или около того на моей довольно хорошей машине, но на других машинах мы видели это намного выше. Мы хотим, чтобы наше приложение для мониторинга запускалось дискретно в фоновом режиме, ища проблемы, а не ели значительную часть процессора.
Это легко может быть воспроизведено простым классом C#. Это загружает все процессы и получает Private Bytes для каждого. Моя машина имеет 150 процессов. CallNextValue займет 1,4 секунды или около 16% процессорного времени
class test
{
List<PerformanceCounter> m_counters = new List<PerformanceCounter>();
public void Load()
{
var processes = System.Diagnostics.Process.GetProcesses();
foreach (var p in processes)
{
var Counter = new PerformanceCounter();
Counter.CategoryName = "Process";
Counter.CounterName = "Private Bytes";
Counter.InstanceName = p.ProcessName;
m_counters.Add(Counter);
}
}
private void CallNextValue()
{
foreach (var c in m_counters)
{
var x = c.NextValue();
}
}
}
Doing это то же самое в Perfmon.exe в окнах и добавление счетчика процесса - Байт со всеми процессами выбран я вижу практически НЕТ процессора подхвачена и это также изображая все процессы.
Итак, как Perfmon получает значения? Есть ли лучший/другой способ получить эти счетчики производительности в C#?
Я пробовал использовать RawValue вместо NextValue, и я не вижу никакой разницы.
Я играл с Pdh-вызовом в C++ (PdhOpenQuery, PdhCollectQueryData, ...). Мои первые тесты не кажутся такими, как на CPP, но я еще не создал хороший образец.
Вы запускаете это через некоторое время (1) или как часто это называется CallNextValue()? Когда у меня была такая же проблема, я использовал потоки, чтобы разделить ее на tpm. другое решение - это не очень хорошо, но для уменьшения количества CPU% поставлен Thread.sleep (5) после каждой итерации не запускает цикл так быстро, как это возможно –
В нашем приложении для мониторинга мы вытаскиваем счетчики каждые 5 секунд , В этом тестовом приложении я просто зацепил кнопку до вызова CallNextValue, и он всегда имеет тот же результат, 16% процессор или около того. – Scott