Как события .NET, потоки и контексты COM работают вместе? - PullRequest
2 голосов
/ 17 ноября 2010

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

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

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

Пока все хорошо.

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

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

Обнаружен отключенный контекст

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

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

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

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

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

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

Ответы [ 2 ]

3 голосов
/ 17 ноября 2010

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

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

2 голосов
/ 17 ноября 2010

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

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

Что это за тип проекта и что означает что делает основной поток?

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

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

...