Именование счетчиков производительности нескольких экземпляров в .NET - PullRequest
11 голосов
/ 07 июня 2010

Большинство счетчиков производительности нескольких экземпляров в Windows, кажется, автоматически (?) Имеют в конце #n, если существует более одного экземпляра с одинаковым именем.

Например: если в Perfmon вы смотритев категории Process вы увидите:

...
dwm
explorer
explorer#1
...

У меня есть два explorer.exe процесса, поэтому ко второму счетчику добавляется # 1 к его имени.

Когда я пытаюсьЧтобы сделать это в приложении .NET:

  • Я могу создать категорию и зарегистрировать экземпляр (используя PerformanceCounterCategory.Create, который принимает CounterCreationDataCollection).
  • Я могуоткройте счетчик для записи и запишите в него.

Когда я открываю счетчик второй раз (в другом процессе), он открывает тот же счетчик.Это означает, что у меня есть два процесса, сражающихся за счетчики.

Документация для PerformanceCounter.InstanceName гласит, что # не допускается в имени.

Итак:Как я могу иметь счетчики производительности нескольких экземпляров, которые на самом деле несколько экземпляров?И где второй (и последующие) экземпляры добавляются #n к имени?

То есть: я знаю, что могу поместить идентификатор процесса (например) в имя экземпляра.Это работает, но имеет неприятный побочный эффект: перезапуск процесса приводит к новому PID, а Perfmon продолжает отслеживать старый счетчик.

Обновление:

I'mсоздаем категорию (и счетчик) следующим образом:

const string categoryName = "Test App";
const string counterName = "Number of kittens";
string instanceName =
    Path.GetFileNameWithoutExtension(
        Process.GetCurrentProcess().MainModule.FileName);

if (!PerformanceCounterCategory.Exists(categoryName))
{
    var counterCreationDataCollection = new CounterCreationDataCollection
        {
            new CounterCreationData(counterName, "",
                PerformanceCounterType.NumberOfItems32)
        };

    PerformanceCounterCategory.Create(categoryName, "",
        PerformanceCounterCategoryType.MultiInstance,
        counterCreationDataCollection);
}

Я открываю счетчик следующим образом:

PerformanceCounter counter = new PerformanceCounter(
        categoryName, counterName, instanceName, readOnly: false);

1 Ответ

2 голосов
/ 15 февраля 2011

Я думаю, что ваша проблема в том, что .NET более свободен в отношении счетчиков производительности и фактически обходит PerfLib Win API.

При использовании собственного API PerfLib вы регистрируете категории во время установки- и создавать экземпляры из процесса, используя дескрипторы.Так что с нативным API нет простого способа поделиться экземпляром счетчика.Поэтому, когда к двум экземплярам счетчика обращаются с одним и тем же именем, они на самом деле имеют разные дескрипторы и помечаются # соответствующим образом.

В .NET, поскольку вы просто обращаетесь к счетчику и экземпляру по имени, вы рискуете пересечьобновления.Поскольку .NET берет имя и перечисляет (используя WMI) экземпляры, даже если они используются другим приложением.

Я думаю, что добавление PID * действительно является самым разумным решением - поскольку у вас обоих лучшетрек-способность и отсутствие столкновений.Что касается проблемы с перезапуском создания нового счетчика, я не вижу проблемы;если вы разрешите запускать более одного экземпляра процесса в определенный момент времени, как вы узнаете, был ли этот экземпляр создан из-за перезапуска или просто запуска другого исполняемого файла?

Если у вас есть какая-то зависимостьмежду процессами вы можете очистить устаревшие счетчики или использовать другую логику.Находясь в PerfMon, вы можете наблюдать "*" все экземпляры.

* Или, если у вас есть какая-то логика позади процесса, которая поддерживается без учета перезапусков - например, некоторый идентификатор задачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...