Но этого не происходит, потому что, как я понял работа с com объектами блокируется во время ожидания WaitOne(). Подскажите как корректно организовать работу с ожиданием событие при работе с Com Interop?
Здравствуйте, bobik1, Вы писали:
B>Но этого не происходит, потому что, как я понял работа с com объектами блокируется во время ожидания WaitOne().
Во время ожидания блокируется вся работа потока. Поток в состоянии "не готов". Вывести его из этого состояния может только другой поток (того же или иного процесса), установив событие.
Подскажите как корректно организовать работу с ожиданием событие при работе с Com Interop?
Здравствуйте, bobik1, Вы писали:
B>Дело в том, что использую библиотеку rtccorelib.
B>Но этого не происходит, потому что, как я понял работа с com объектами блокируется во время ожидания WaitOne(). Подскажите как корректно организовать работу с ожиданием событие при работе с Com Interop?
Похоже, Вы создаёте COM-объект из Single Threaded Apartment (STA). Судя по всему, работу, инициированную вызовом DisableProfile, этот объект выполняет в отдельном потоке, но так как Вы создали его из STA, то событие он пытается оттранслировать в этот Ваш STA поток, а COM такую трансляцию выполняет с помощью оконных сообщений. Для получения-же сообщений поток должен "крутить" message loop, но Ваш поток в это время сидит в WaitOne и получить их не может.
Другая возможная, хотя и менее вероятная причина — самой DisableProfile нужен цикл выборки сообщений.
Есть множество способов разрулить такую ситуацию, вплоть до "полу-хакерских", но без знания деталий предложить что-либо достаточно оптимальное вряд-ли возможно.
"Нормальные герои всегда идут в обход!"
Re[2]: Блокировка Com Interop при ожидании WaitOne
Здравствуйте, Jolly Roger, Вы писали:
JR>Похоже, Вы создаёте COM-объект из Single Threaded Apartment (STA). Судя по всему, работу, инициированную вызовом DisableProfile, этот объект выполняет в отдельном потоке, но так как Вы создали его из STA, то событие он пытается оттранслировать в этот Ваш STA поток, а COM такую трансляцию выполняет с помощью оконных сообщений. Для получения-же сообщений поток должен "крутить" message loop, но Ваш поток в это время сидит в WaitOne и получить их не может.
Кстати. В Win API есть такая функция
MsgWaitForMultipleObjects
Она как раз разруливает эту ситуацию. Ждем, но если в очереди появится сообщение, то ожидание прекращаем. Иными словами, ждем объекты или сообщение. Есть аналог в .NET ?
With best regards
Pavel Dvorkin
Re[3]: Блокировка Com Interop при ожидании WaitOne
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Кстати. В Win API есть такая функция
PD>MsgWaitForMultipleObjects
PD>Она как раз разруливает эту ситуацию. Ждем, но если в очереди появится сообщение, то ожидание прекращаем. Иными словами, ждем объекты или сообщение.
Я её и имел в виду, говоря о "полу-хакерских" способах. Дело в том, что просто вызвать Message loop после её срабатывания зачастую бывает неприемлемо. Нужно ставить фильтр на "COMовские" сообщения, а так как они не документированы, то к легальным этот способ отнести трудно
С другой стороны, если моя гипотеза по поводу STA верна, то можно обойтись вообще без Event'а, достаточно WaitMessage, PeekMessage с фильтром и флага, но и этот способ страдает теми-же недостатками.
Я бы рекомендовал прежде всего рассмотреть возможность использования MTA, либо вынос ожидания в доп. поток.
PD>Есть аналог в .NET ?
Не знаю, по-моему нет, но в любом случае импортировать не проблема.
"Нормальные герои всегда идут в обход!"
Re[2]: Блокировка Com Interop при ожидании WaitOne
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, bobik1, Вы писали:
B>>Но этого не происходит, потому что, как я понял работа с com объектами блокируется во время ожидания WaitOne().
PD>Во время ожидания блокируется вся работа потока. Поток в состоянии "не готов". Вывести его из этого состояния может только другой поток (того же или иного процесса), установив событие.
PD>Подскажите как корректно организовать работу с ожиданием событие при работе с Com Interop?
PD>COM тут особой роли не играет.
CoWaitForMultipleHandles:
If the caller resides in a single-thread apartment, CoWaitForMultipleHandles enters the COM modal loop, and the threads message loop will continue to dispatch messages using the threads message filter. If no message filter is registered for the thread, the default COM message processing is used.
If the calling thread resides in a multithread apartment (MTA), CoWaitForMultipleHandles calls the Win32 function MsgWaitForMultipleObjects.
Re[4]: Блокировка Com Interop при ожидании WaitOne
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Кстати. В Win API есть такая функция
PD>>MsgWaitForMultipleObjects
PD>>Она как раз разруливает эту ситуацию. Ждем, но если в очереди появится сообщение, то ожидание прекращаем. Иными словами, ждем объекты или сообщение.
JR>Я её и имел в виду, говоря о "полу-хакерских" способах. Дело в том, что просто вызвать Message loop после её срабатывания зачастую бывает неприемлемо. Нужно ставить фильтр на "COMовские" сообщения, а так как они не документированы, то к легальным этот способ отнести трудно
JR>С другой стороны, если моя гипотеза по поводу STA верна, то можно обойтись вообще без Event'а, достаточно WaitMessage, PeekMessage с фильтром и флага, но и этот способ страдает теми-же недостатками.
JR>Я бы рекомендовал прежде всего рассмотреть возможность использования MTA, либо вынос ожидания в доп. поток.
PD>>Есть аналог в .NET ?
JR>Не знаю, по-моему нет, но в любом случае импортировать не проблема.
Это обычное оконное приложение [STAThread]. Попробовал поставить [MTAThread], перестала работать другая ActiveX компонента, которую использует мое приложение:
"Создание экземпляра элемента управления ActiveX \"fa7a5eb0-d402-11d2-a719-00c00cb08f5b\" невозможно: текущий поток не находится в однопоточном контейнере."
Спасибо, буду пробовать другие ваши советы.