Счетчик производительности использование процессора для текущего процесса составляет более 100
Я хочу отобразить использование процессора для моего многопоточного приложения (работа над многоядерным процессором). Я хочу получить номера, близкие к номеру диспетчера задач, но я получил номера более чем на 100%. Даже больше чем на 500%. Да, я знаю, чем счетчик "% процессорного времени " для категории "Процесс" Мне нужно разделить на окружение.ProcessorCount или "NumberOfLogicalProcessors" (то же самое для моей конфигурации). И 500% - это результат после этой операции. Я проверил это пример на разных компьютерах с различным оборудованием (i7, i5, Core2) и конфигурациями программного обеспечения (Windows 7 SP1 со всеми обновлениями, Windows 2008 R2 SP1 со всеми обновлениями) и получил ту же проблему.
public static class SystemInfo
{
private static Process _thisProc;
private static bool HasData = false;
private static PerformanceCounter _processTimeCounter;
private static void Init()
{
if (HasData)
return;
if (CheckForPerformanceCounterCategoryExist("Process"))
{
_processTimeCounter = new PerformanceCounter();
_processTimeCounter.CategoryName = "Process";
_processTimeCounter.CounterName = "% Processor Time";
_processTimeCounter.InstanceName = FindInstanceName("Process");
_processTimeCounter.NextValue();
}
MaximumCpuUsageForCurrentProcess = 0;
HasData = true;
}
private static bool CheckForPerformanceCounterCategoryExist(string categoryName)
{
return PerformanceCounterCategory.Exists(categoryName);
}
public static string FindInstanceName(string categoryName)
{
string result = String.Empty;
_thisProc = Process.GetCurrentProcess();
if (!ReferenceEquals(_thisProc, null))
{
if (!String.IsNullOrEmpty(categoryName))
{
if (CheckForPerformanceCounterCategoryExist(categoryName))
{
PerformanceCounterCategory category = new PerformanceCounterCategory(categoryName);
string[] instances = category.GetInstanceNames();
string processName = _thisProc.ProcessName;
if (instances != null)
{
foreach (string instance in instances)
{
if (instance.ToLower().Equals(processName.ToLower()))
{
result = instance;
break;
}
}
}
}
}
}
return result;
}
public static int CpuUsageForCurrentProcess
{
get
{
Init();
if (!ReferenceEquals(_processTimeCounter, null))
{
int result = (int) _processTimeCounter.NextValue();
result /= Environment.ProcessorCount; //NumberOfLogicalProcessors //same for me
if (MaximumCpuUsageForCurrentProcess < result)
MaximumCpuUsageForCurrentProcess = result;
return result;
}
return 0;
}
}
public static int MaximumCpuUsageForCurrentProcess { private set; get; }
}
И код для выполнения (вам нужно создать приложение windows forms с двумя ярлыками, одним BackgroundWorker и одной кнопкой)
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
IList<Task> tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
Task t = new Task(() =>
{
do {
if (backgroundWorker1.CancellationPending)
break;
} while (true);
});
t.Start();
tasks.Add(t);
}
Task displayProgress = new Task(() => { do {
if (backgroundWorker1.CancellationPending)
break;
backgroundWorker1.ReportProgress(1);
Thread.Sleep(10);
} while (true); });
displayProgress.Start();
tasks.Add(displayProgress);
Task.WaitAll(tasks.ToArray());
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text = SystemInfo.CpuUsageForCurrentProcess.ToString();
label2.Text = SystemInfo.MaximumCpuUsageForCurrentProcess.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = SystemInfo.CpuUsageForCurrentProcess.ToString();
if (backgroundWorker1.IsBusy)
backgroundWorker1.CancelAsync();
else
backgroundWorker1.RunWorkerAsync();
}
Пожалуйста, покажите мне мои ошибки. И да, я прочитал эту статью и заметил, что
"Process (...)% Processor Time " может пойти вверх до N * 100 (где N-число процессоров), поскольку он суммирует использование ЦП запрошенного процесса во всех процессорах.
1 ответ:
Этот (несколько связанный) вопрос предполагает использование системы .Диагностика.Процесс.TotalProcessorTime и система.Диагностика.Процесс чтения.Свойства TotalProcessorTime вместо этого, для низких накладных расходов и легкой реализации.
(Edit: Вот статья, объясняющая, как использовать свойства, а также.)
Кроме того, похоже, что вы недостаточно долго ждете между вызовами "_processTimeCounter.NextValue ()."Согласно документации , вы должны подождать хотя бы 1 секунду. Не уверен, вызовет ли это ваши странные цифры или нет.