Как получить имя события из дескриптора

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

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

Кто-нибудь знает, как получить имя события или лучший способ сделать это?


person Community    schedule 14.10.2009    source источник


Ответы (3)


Лично я бы так не поступил. Создайте свое собственное сопоставление (std::map?) между событием и именем ключа, а затем выполните собственный поиск, когда сигнализируется событие.

person Len Holgate    schedule 14.10.2009
comment
Это мой текущий план. Просто выглядит не очень элегантно - person ; 14.10.2009
comment
В этой ситуации карта, вероятно, излишняя — вектор должен работать нормально. Просто поместите имена в векторе в том же порядке, что и соответствующие дескрипторы в массиве, который вы передаете WMFO. Тогда индекс, возвращаемый WMFO, также будет действовать как индекс имен. - person Jerry Coffin; 14.10.2009
comment
Карта была бы лучше, чем выравнивание двух массивов вручную. Накладные расходы незначительны. - person Kieveli; 14.10.2009
comment
Какие трудности могут быть в том, чтобы удержать их на одной линии? В типичном коде это происходило бы автоматически — например, вы использовали бы вектор для каждого, и когда вы получаете имя для просмотра, использовали бы push_back, чтобы добавить его к вектору имен, а затем использовали бы push_back, чтобы добавить имя. ручка к вектору ручек. Точно так же, когда вы удаляете один, вы обычно используете одну и ту же технику (например, удаление/стирание) для обоих, снова автоматически сохраняя тот же порядок. - person Jerry Coffin; 14.10.2009
comment
Джерри, хорошее место. Я согласен, вектор имен должен легко синхронизироваться с вектором дескрипторов. Одна вещь, которую я бы добавил, это то, что лично у меня было бы дополнительное событие в качестве первого события для ожидания, это было бы событие «пожалуйста, прекратите ждать СЕЙЧАС», которое можно использовать, когда вы хотите выключить или уничтожить класс, который заключает все это. - person Len Holgate; 14.10.2009
comment
Это не проблема, когда вы впервые добавляете его, если вы осторожны. Это происходит после того, как третий человек модифицировал класс, сделал один из векторов общедоступным, а затем позволил какому-то другому классу изменить его напрямую. Карта более прямолинейна. - person Kieveli; 14.10.2009
comment
@Len, да, у меня есть событие, чтобы перестать слушать, и оно всегда находится в позиции 0. @Jerry, я использовал подход с двойным вектором. Я имел это в виду, прежде чем публиковать вопрос, но кажется странным, что вы не можете получить название события. - person ; 15.10.2009
comment
@Kieveli Вы пинаете их, когда они делают это общедоступным; вы можете использовать это оправдание для любого плохого дизайнерского решения ... @DotNetWill - имена событий (и других объектов ядра) не предназначены для такого использования. Не борись с этим. - person Len Holgate; 15.10.2009

Вероятно, вы могли бы сделать это с помощью недокументированных материалов NT, может быть, NtQueryObject(handle,ObjectNameInformation,....)

person Anders    schedule 15.10.2009

Обычно имя события используется для вызова OpenEvent() для получения дескриптора. Таким образом, вам не нужно сообщать дескриптор во время выполнения, а вместо этого соглашайтесь на соглашение об именах для имени события.

Я могу придумать три способа сделать это:

  • Переберите все жестко запрограммированные имена событий и вызовите OpenEvent().
  • Сохраните дескрипторы и имена в std::map
  • Создайте класс для хранения ваших дескрипторов и имен (возможно, в std::map) и напишите методы для быстрого получения имени из дескриптора.

Вы решаете, какие действия предпринять, основываясь на названии события? Оператор if else if, который проверяет имена дескрипторов один за другим, чтобы определить, какое действие предпринять? Такой сценарий обычно заставляет меня рассматривать наследование как потенциальное решение. Потерпи немного.

Что, если вы создадите базовый класс, скажем, EventAction. У него есть дескриптор события и виртуальная функция-член go_go_commandos(). Вы получаете его для каждого «события», которое должно быть выполнено, и реализуете действие в методе go_go_commandos() каждого производного класса.

Теперь вам нужен контейнер, чтобы вы могли сказать actionlist->GetEventAction(handle)->go_go_commandos().

Это вообще помогло?

person Kieveli    schedule 14.10.2009
comment
Я понимаю, к чему вы клоните, но я пытаюсь создать наблюдателя за реестром только для значений и иметь несколько объектов, которые хотят знать об изменениях значений в ключе. Поэтому мне нужно посмотреть соответствующие ключи, затем выяснить, какие значения изменились, а затем вызвать только интересующие объекты. Если это имеет смысл. Win32 предлагает это не только для просмотра ключей. - person ; 14.10.2009
comment
Думаю, я до сих пор не понимаю, зачем вам нужно искать имя события с заданным дескриптором. - person Kieveli; 14.10.2009
comment
НЕ используйте имя, доступное в OpenEvent(). Это делает ваш объект общим для процессов, используя это имя. С LPSA NULL ваш объект будет широко открыт для манипуляций, и у вас будет дыра в безопасности. Идея карты Лена Холгейта очень проста, я бы пошел по этому пути. - person Heath Hunnicutt; 14.10.2009
comment
@Kieveli В то время мой разум работал именно так, картографический / векторный подход лучше. @ Хит. Спасибо, я этого не знал и сейчас изменил :) - person ; 15.10.2009