COM: вызов из другого потока вызывает сбои, как заставить его работать в том же потоке? - PullRequest
3 голосов
/ 14 октября 2008

Я делаю BHO (расширение для IE), который получает события в другом потоке. Когда я получаю доступ к DOM из этого другого потока, IE падает. Можно ли сделать доступ к DOM из того же потока, что и основной поток BHO, чтобы он не зависал?

Кажется, это общая проблема многопоточности COM, которую я не очень понимаю.

Ответы [ 4 ]

3 голосов
/ 14 октября 2008

Изучите использование CoMarshalInterface или CoMarshalInterThreadInterfaceInStream

Это даст вам обернутый интерфейс для STA COM-объекта, который является потокобезопасным.

1 голос
/ 14 октября 2008

Я не знаю много о расширениях IE, но, похоже, некоторые COM-объекты должны быть помечены как однопотоковые, так что система времени выполнения COM гарантирует, что она будет запущена в том же потоке, который первоначально вызывал ее. Если вы не можете изменить другой объект, вы можете, вероятно, перенаправить свои вызовы в DOM через отдельный COM-объект, помеченный как STA, для достижения того же эффекта. Надеюсь, это поможет ... Я немного знаю о многопоточности COM, но немного о расширениях IE.

0 голосов
/ 12 марта 2015

Будьте осторожны, хотя. Производительность может стать серьезной проблемой.

Если вы просто играете, чтобы узнать о BHO, вы можете использовать STA, чтобы заставить реализующий объект :: SetSite () работать так, как если бы он был однопоточным (это позволяет другим потокам вытягивать указатель вашего BHO GlobalInterfaceTable, как упоминает @JasonS.

Если вы делаете что-то, что, как ожидается, станет частью продукта, я настоятельно рекомендую вам очень тщательно пересмотреть возможность использования MTA везде, где только можно, и самостоятельно решать проблемы параллелизма и безопасности потоков. В этом случае вам нужно будет только убедиться, что потоки, взаимодействующие с вашим BHO COM-объектом, сами были инициализированы для COM.

Например, если вы хотите отслеживать входящие / исходящие данные веб-сайта в поисках вещей (как опасных, так и чувствительных) - тогда вам НЕ нужно заставлять все эти потоки опускаться до горла объекта STA, потому что, используя Yahoo как Например, будет запущено более 30 запросов, и ваш BHO начнет блокировать IE.

0 голосов
/ 10 декабря 2008

Ах, весело, весело, весело, многопоточность с COM.

Ответ Джеральда выглядит правильно, если вы хотите передать указатель интерфейса из одного потока в другой ровно один раз. Я обнаружил, что GIT (глобальная таблица интерфейсов) - большая помощь для такого рода вещей, если вы работаете в многопоточной системе ... в основном вы не храните указатели на интерфейсы, а скорее файлы cookie DWORD, используемые GIT получить маршалированный интерфейсный указатель для любого потока, который вы используете. (Вы должны сначала зарегистрировать данный объект в GIT, а затем отменить его регистрацию, когда закончите или закончите свой объект)

...