Просмотр глобальных событий, созданных собственным процессом в процессе .NET

У меня есть глобальное событие, созданное и установленное/сброшенное в собственном процессе С++, которое создается следующим образом:

HANDLE hGlobalEvent = CreateEvent(NULL, TRUE, FALSE, _T("Global\\MyEvent"));

Есть ли способ (даже если это библиотека, написанная не MS), чтобы зарегистрироваться для одного из этих событий в процессе .NET (C#), чтобы стандартные обработчики событий .NET срабатывали при изменении глобального события?
И я на самом деле не хочу просто ждать события и зацикливаться, как это делается в C++ с помощью WaitForSingleObject... Я действительно хотел бы, чтобы это был полностью асинхронный обработчик событий.

Я должен представить, что есть простой способ сделать это... просто не могу его найти.


person Adam Haile    schedule 17.05.2009    source источник


Ответы (1)


ThreadPool.RegisterWaitForSingleObject можно использовать для выполнения обратного вызова при появлении сигнала о событии. . Получите объект WaitHandle для именованного объекта события с помощью конструктора EventWaitHandle, который принимает имя строки.

bool createdNew;
WaitHandle waitHandle = new EventWaitHandle(false,
    EventResetMode.ManualReset, @"Global\MyEvent", out createdNew);
// createdNew should be 'false' because event already exists
ThreadPool.RegisterWaitForSingleObject(waitHandle, MyCallback, null,
    -1, true);

void MyCallback(object state, bool timedOut) { /* ... */ }
person Bradley Grainger    schedule 17.05.2009
comment
EventWaitHandle будет открывать событие, созданное в процессе Win32, а не создавать новое событие, верно? - person Adam Haile; 17.05.2009
comment
Да, и есть перегрузка конструктора, которую вы можете вызвать, чтобы убедиться в этом; у него есть логический параметр «out», который сообщает вам, существовало ли событие уже или было создано конструктором. В вашем случае значение out должно быть ложным. Я обновил фрагмент кода, чтобы показать это. - person Bradley Grainger; 18.05.2009
comment
Потрясающе... спасибо за обновление. Это действительно помогло. И теперь, возможно, решение этого вопроса действительно появится в гугле :) - person Adam Haile; 18.05.2009
comment
Хорошо ... это работает. Проблема в том, что мне нужно знать фактическое состояние события, и все это дает мне то, что я передал для третьего параметра в RegisterWait. Кроме того, если я оставлю последний параметр как true, он сработает только один раз, и мне придется продолжать перерегистрацию, но если я установлю для него значение false, он просто бесконечно вызывает обратный вызов после изменения состояния события... хотя я до сих пор не знаю, что это за состояние... - person Adam Haile; 18.05.2009
comment
Чтобы уточнить немного больше... в C++ ожидание события возвращается только тогда, когда состояние события изменяется на сигнальное (истинное), но не когда оно меняется обратно на несигнальное (ложное)... поэтому вы по своей сути знаете состояние. Вы также можете вызвать ожидание с тайм-аутом 0, и если он возвращает WAIT_OBJECT, состояние истинно, а если WAIF_TIMEOUT — ложно. Но этот код С#, кажется, запускает обратный вызов всякий раз, когда состояние вообще изменяется.... - person Adam Haile; 18.05.2009
comment
В исходном коде, который вы дали, второй аргумент CreateEvent равен TRUE, указывая на то, что это событие с ручным сбросом. Если событие не сброшено, обратный вызов будет продолжать выполняться, потому что базовое событие все еще сигнализируется. Если функция обратного вызова отвечает за сброс события, вызовите «waitHandle.Reset()» в MyCallback. Если вы ожидаете, что кто-то другой сбросит событие, я не уверен, что это хороший способ выполнить обратный вызов только один раз, пока событие не будет сброшено, а затем снова установить. - person Bradley Grainger; 18.05.2009
comment
Понял... Я понял это. К счастью, я упустил из исходного кода то, что на самом деле было два события: одно для подключения и одно для отключения (оно отслеживает USB-сканер штрих-кода). Итак, что я в итоге сделал, так это проверил начальное состояние обоих при запуске, затем отслеживая несигнальное событие и чередуя с другим событием, когда оно было сигнализировано. Переключение туда и обратно решило мою проблему. Спасибо за помощь! - person Adam Haile; 19.05.2009