Счетчик производительности использование процессора для текущего процесса составляет более 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 13

1 ответ:

Этот (несколько связанный) вопрос предполагает использование системы .Диагностика.Процесс.TotalProcessorTime и система.Диагностика.Процесс чтения.Свойства TotalProcessorTime вместо этого, для низких накладных расходов и легкой реализации.

(Edit: Вот статья, объясняющая, как использовать свойства, а также.)

Кроме того, похоже, что вы недостаточно долго ждете между вызовами "_processTimeCounter.NextValue ()."Согласно документации , вы должны подождать хотя бы 1 секунду. Не уверен, вызовет ли это ваши странные цифры или нет.