Какова лучшая практика для отслеживания производительности? Система.Диагностика или Система.Менеджмент?

Я хочу внедрить систему, которая отслеживает текущие процессы. Система получает информацию о высокой нагрузке (процессор, память и т. Д.). Я исследую два пространства имен. Это Система. Диагностика и Система. Управление. Сначала я написал класс для отображения имен, идентификаторов и загрузки ЦП всех запущенных процессов.

class Program
{
    static void Main()
    {
        Console.WriteLine("--------------using System.Diagnostics---------------------");
        SysDi();

        Console.WriteLine("----using System.Diagnostics CPU load always zero----------");

        //Here CPU load always zero
        SysDiCpuZero();

        Console.WriteLine("--------------using System.Management---------------------");
        Vmi();

    }


    static void Vmi()
    {
        try
        {
            var searcher = new ManagementObjectSearcher("root\\CIMV2",
                "SELECT * FROM Win32_PerfFormattedData_PerfProc_Process");

            foreach (var queryObj in searcher.Get())
            {
                Console.WriteLine($"Process: {queryObj["Name"]} " +
                                  $"ID: {queryObj["CreatingProcessID"]} " +
                                  $"CPU load: {queryObj["PercentProcessorTime"]}");
            }
        }
        catch (ManagementException e)
        {
            Console.WriteLine("An error occurred while querying for WMI data: " + e.Message);
        }
    }

    static void SysDi()
    {
        var processlist = Process.GetProcesses();
        var counters = new List<PerformanceCounter>();
        foreach (var theprocess in processlist)
        {
            var counter = new PerformanceCounter("Process", "% Processor Time", theprocess.ProcessName);

            counter.NextValue();
            counters.Add(counter);
        }

        var i = 0;


        Thread.Sleep(10);
        foreach (var counter in counters)
        {
            Console.WriteLine($"Process: {processlist[i].ProcessName} " +
                              $"ID: {processlist[i].Id} " +
                              $"CPU load: {Math.Round(counter.NextValue(), 5)}");
            ++i;
        }
    }

    static void SysDiCpuZero()
    {
        var processlist = Process.GetProcesses();

        foreach (var theprocess in processlist)
        {
            var counter = new PerformanceCounter("Process", "% Processor Time", theprocess.ProcessName);
            counter.NextValue();

            Console.WriteLine($"Process: {theprocess.ProcessName} " +
              $"ID: {theprocess.Id} " +
              $"CPU load: {Math.Round(counter.NextValue(), 5)}");
        }
    }
}

Также я заметил, что в разных пространствах имен одни и те же свойства имеют разные значения. Кроме того, System.Diagnostic быстрее, чем System.Management, но метод SysDi() с загрузкой данных процессора выглядит неясным.

Что лучше использовать в моем случае? Каким критериям я должен следовать, чтобы выбрать?

2 ответа

Используя ваш код и упаковку StopWatchвокруг него вот результат (мс):

WithWMI: 4ms 
WithoutWMI: 2ms

Это от одного звонка, поэтому с помощью Process.GetProcess() быстрее, но также легче читать (по моему мнению), вам не нужно беспокоиться о волшебных строках (запрос, например).

После запуска несколько раз, кажется, что с помощью Process.GetProcess() быстрее, в некоторых запусках они оба занимают одинаковое количество времени, но обычно Process.GetProcess() быстрее купить несколько мс.

Кроме того, если вам не нужно использовать WMI, не используйте WMI, как известно, медленнее.

Также кажется, что при запросе ManagementObjectSearcher он может использовать больше процессора по сравнению с вызовом Process.GetProcess()Я заметил это, вызвав их оба 10000 раз, и WMIProvierHost использовал процессор на 50% весь путь (я знаю, что это не нормальный случай использования объекта WMI 1000 раз).

Но разница во времени между двумя вызовами на самом деле почти ничего не значит, все сводится к удобочитаемости, и я всегда буду использовать Process.GetProcess по запросу WMI для процессов.

Используйте все, что проще и чище. В будущем вы можете расширить функциональность, и ваш проект может вырасти. Простота начального шага окупится позже. WMI предназначен для того, чтобы делать все возможное, но с большими накладными расходами. Для большинства случаев Diagnostics достаточно хорошо, хотя.

Вопросы времени могут сыграть свою роль, но я не думаю, что вы хотите постоянно проверять процессы, поэтому это не должно быть очень важным. Тем не менее, этот аспект также указывает на Diagnostics,

Обновить

Чтобы получить нагрузку на процессор, вы можете использовать класс PerformanceCounter из Diagnostics Пространство имен.

Другие вопросы по тегам