2010-11-17 2 views
2

У меня есть COM-объект, разработанный на C++. Этот класс использует другой (сторонний) COM-объект, который выдает событие EvtThirdParty. Этот сторонний объект - это всего лишь метод моего класса.Как работают события .NET, потоки и COM-контексты?

Теперь я использую свой COM-объект из приложения .NET (Visual Basic для чего это стоит), и я хотел бы поймать EvtThirdParty из приложения Visual Basic.

Я предполагаю, что нет никакого тривиального способа сделать это, но пусть эта информация здесь на всякий случай, если кто-то укажет один. Итак, я добавил одно событие (EvtThirdPartyDummy) к моему COM-объекту, и всякий раз, когда он захватывает EvtThirdParty, возникает EvtThirdPartyDummy для VB.NET.

До сих пор так хорошо.

Теперь, когда приложение получает это событие, оно должно сделать пару звонков на мой объект, чтобы получить некоторую информацию.

Вот где мои проблемы начинаются. Я получаю странное сообщение об отсоединенном контексте: был обнаружен

отсоединен Контекст

Сообщение: Контекст 0x1b9351e0' является отсоединен. Освобождение интерфейсов из текущего контекста (контекст 0x1b934f90). Это может привести к повреждению или потере данных. Чтобы избежать этой проблемы, пожалуйста, убедитесь, что все контексты/квартиры остаются в живых до тех пор, приложение полностью сделано с RuntimeCallableWrappers, что представляют COM-компоненты, которые живут внутри них.

Я не совсем уверен, что это ТОЧНО сообщение я получаю, так как мой Визуальный   Студия   2005 на испанском языке, и я нашел в Google, но это, кажется, достаточно близко. Есть некоторые отличия (например, название моего сообщения говорит «Visual Studio 2005», IIRC, но это может быть связано с другой версией IDE).

Для того, что я нашел в Google, кажется, что поток, в котором был создан объект, был уничтожен, но я уверен, что это не так. Он создается в основном потоке приложения.

Если я удалю весь код из обработчика событий, все работает как шарм.

Мое лучшее предположение, что мое мероприятие обрабатывается в совершенно новом потоке, но AFAIK это не должно быть так.

Что происходит?

+1

Так соблазн ответить «Плохо» – Basic

ответ

3

Это предупреждение от управляемого помощника по отладке, документы are here. Хотя это предупреждение, вы не должны игнорировать, если это происходит во время обратного вызова. Это, как правило, проблема с потоками, поток, которому принадлежит COM-объект, вышел из него. Или позвоните CoUnitialize(), чтобы снести его квартиру. То же самое, выход из потока вызывает CoUnitialize().

В вашем вопросе мало, что действительно помогает придумать достойную диагностику для этого. Учтите, что этот сторонний COM-компонент может иметь какое-то отношение к нему, например, поднимать событие в другом потоке. Окно Debug + Windows + Threads должно помочь с этим. Обратите внимание на окно вывода, оно показывает уведомления о завершении потока.

+0

Кажется, что ваша догадка правильная, событие работает в другом потоке. Нет уведомлений о прекращении потока. Теперь решение должно быть простым, я думаю ... Большое спасибо, Ханс, ваш ответ очень полезен, как всегда. – raven

+0

Ну, я решил это довольно нелегко. Но все-таки решил. – raven

2

Во-первых, это не моя сильная сторона, но, как вы не имели никаких ответов пока ...

События подняты на разных потоках, так что вы сказали о том, на другом потоке звучит разумно. Вы можете попробовать позвонить Invoke() в обработчик события, чтобы вернуть основной поток и изучить объект после того, как событие было поднято.

Какой проект и что такое is Основная тема?

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

Как я уже сказал, я далек от эксперта по этому вопросу, поэтому, возможно, другие смогут дать вам лучшие ответы.

+0

Большое спасибо за ваш ответ. Нет пользовательского интерфейса, это просто сервер, который слушает сеть и отвечает соответственно. Я не знал об Invoke, расследую его немного дальше, спасибо. – raven

+0

Я не могу использовать Invoke, потому что у меня нет пользовательского интерфейса. Черт, было бы так удобно ... – raven

+0

Закон Мерфи снова наносит удар :) – Basic

Смежные вопросы