Счетчик производительности создан, но не работает до перезапуска Windows

У меня странная проблема с созданием новых счетчиков в существующей группе. У меня есть служба Windows, которая выполняет некоторую работу и позволяет мне контролировать ее состояние с помощью счетчика производительности. У меня есть группа счетчиков производительности и некоторые счетчики производительности. Группа создается на этапе установки службы (с правами администратора), а счетчики инициализируются при запуске службы (как пользователь LocalSystem). Все работает отлично, существует группа, существует счетчик, я могу контролировать их и записывать в журнал счетчиков производительности. Служба постоянно работает.

Затем я хочу добавить еще несколько счетчиков производительности. Я добавляю их в код службы, перестраиваю и развертываю на сервер, удаляя предыдущий экземпляр службы (группа счетчиков производительности удаляется кодом удаления) и снова устанавливая службу (группа счетчиков производительности создается во время фазы установки со всеми новыми счетчиками). Затем я запускаю сервис.

Это конец общей, неинтересной части истории. Странные вещи начинаются здесь.

Я перехожу к PerMon, добавляю все счетчики в представление системного монитора. Я вижу группу показателей производительности, я вижу все счетчики производительности, включая новые счетчики производительности, которые я только что добавил. Я могу добавить их в представление системного монитора. И я вижу, что старые счетчики работают. Но новые счетчики не работают, они не собирают никаких данных. Ну, хорошо, возможно, была моя ошибка, я переключился на просмотр журнала и попытался записать данные счетчиков производительности. Старые счетчики регистрируются по мере их регистрации. Но когда я пытаюсь добавить новый счетчик, я вижу в Event Viewer следующее предупреждение:

Службе не удалось добавить счетчик '\ AGENT\MyCountersGroupName\MyNewCounter' в журнал или оповещение NewCountersLog. Этот журнал или предупреждение будут продолжены, но данные для этого счетчика не будут собраны. Возвращенная ошибка: указанный счетчик не найден.

Я попытался переустановить службу, удалить старые счетчики, добавить их снова, и ничего не изменилось. Старые счетчики работают, а новые счетчики не работают. Затем я перезапускаю Windows, и новые счетчики начали работать! Ничего не изменилось в сервисе, я только что перезапустил сервер. Я столкнулся с этой проблемой на двух серверах, оба из них работают под управлением Windows Server 2003 с пакетом обновления 1 (SP1). Код для всех счетчиков производительности идентичен, потому что я создаю их с помощью кода с дженериками.

Вы можете сказать: "Эй, не беспокойтесь, перезагружайте Windows каждый раз, когда вам нужно добавить новые счетчики производительности", но я не могу. Моя служба работает на сервере вместе с другими службами, и нам нужны эти службы постоянно, мы не можем перезагружать сервер каждый раз, когда меняю одну службу.

Может ли кто-нибудь помочь в решении этой проблемы?

Update: Похож на аналогичную проблему: https://stackoverflow.com/info/2180005/adding-performance-counters-to-existing-category

Обновление Я не думаю, что проблема в моем коде, но если это помогает, я публикую его здесь.

Код для установки и удаления (вызывается на этапе установки): PerformanceCountersManagerBase.GetCreationData() - это общая оболочка для сбора данных для создания счетчиков производительности.

public static void Install()
{
    CounterCreationDataCollection counters = new CounterCreationDataCollection(
    PerformanceCountersManagerBase.GetCreationData<TManager>().ToArray());

    if (PerformanceCounterCategory.Exists(PerformanceCountersManagerBase.GroupName))
        PerformanceCounterCategory.Delete(PerformanceCountersManagerBase.

    PerformanceCounterCategory.Create(PerformanceCountersManagerBase.GroupName, 
        "Group description",
        PerformanceCounterCategoryType.SingleInstance, counters);
}

public static void Uninstall()
{
    if (!PerformanceCounterCategory.Exists(PerformanceCountersManagerBase.GroupName))
        return;

    PerformanceCounterCategory.Delete(PerformanceCountersManagerBase.GroupName);
}

Код для инициализации счетчиков в службе и обновлении:

internal void Initialize(string name, string groupName)
{
    _counter = new PerformanceCounter(groupName, name, false);
    _counter.RawValue = 0;
}

internal void Increment()
{
    if ((_counter == null) || _counter.ReadOnly)
        return;

    lock (_counter)
    {
        _counter.Increment();
    }
}

Обновление 3 Я изменил код для установки счетчиков через компонент .NET PerformanceCounterInstaller, и ничего не изменилось. Старые счетчики работают так, как они работали, а недавно созданные не работают и пытаются записать их в результате точного сообщения об ошибке (предупреждение) в журнале событий. Код создания установщика выглядит следующим образом:

public static PerformanceCounterInstaller GetInstaller()
{
    PerformanceCounterGroupAttribute group
        = PerformanceCountersManagerBase.ExtractGroupSettings(typeof(TManager));

    PerformanceCounterInstaller installer = new PerformanceCounterInstaller();
    installer.CategoryName = group.Name;
    installer.CategoryHelp = group.Description;
    installer.CategoryType = PerformanceCounterCategoryType.SingleInstance;
    installer.UninstallAction = UninstallAction.Remove;
    installer.Counters.AddRange(PerformanceCountersManagerBase.GetCreationData<TManager>().ToArray());

    return installer;
}

Ответ 1

Счетчики Perf основаны на сегментах разделяемой памяти. Я видел подобные проблемы, когда у кого-то еще есть дескриптор сегмента разделяемой памяти. Это может включать сам инструмент perfmon. Вы можете использовать утилиту handle, чтобы узнать, кто держит ее в общей памяти. Вам не нужно перезагружаться, поэтому постарайтесь выяснить, не исчезла ли эта проблема, вы сначала закрыли перфоман, а затем снова создали счетчики. Также убедитесь, что ваша служба не запущена.

Ответ 2

До ответа Майка я сам справился с проблемой. Но у меня нет времени, чтобы выяснить причину проблемы. Я решил проблему, выполнив следующие шаги:

  • остановить ведение журнала perfmon (я зарегистрировал все свои счетчики через регистратор perfmon)
  • закрыть perfmon
  • удалить сервис (деинсталлятор службы удалять счетчики производительности целая группа)
  • установить службу с добавленными счетчиками производительности

После этих шагов появились новые счетчики производительности. Возможно, нет необходимости останавливать ведение журнала, но у меня нет времени проверить это на данный момент. Я попробую это позже. Я принимаю Майка как правильный, поскольку он указывает на причину проблемы.

Ответ 3

У меня был аналогичный случай, когда я создал некоторые счетчики производительности для разных сегментов моей системы и добавлял их в словарь для прямого доступа по имени, и все они написали один для всех (любой шаг на любом из них обновлял бы остальное).

Для моего удивления решение заключалось в ЗАКРЫТЬ инструмент Performance Monitor, а затем создать счетчики. Проблема заключалась в использовании памяти с разделяемой памятью, которая была заблокирована.