Маршалу или не маршалу

Я не смог найти однозначного ответа на следующий вопрос: если COM-класс является потокобезопасным, то есть он помечен как Both или Free, мне действительно нужно маршалировать его интерфейс объекта, чтобы передать его другому потоку в том же процессе? Я не спрашиваю о случае, если оба потока принадлежат MTA, я спрашиваю о случае, когда каждый поток принадлежит своей собственной STA.

Я знаю о правиле маршалировать интерфейсы между потоками, которые принадлежат разным квартирам, мой вопрос: что произойдет, если я передам необработанный указатель интерфейса на поток в другой квартире, и каждый поток вызовет методы для объекта, который является потокобезопасным?

Судя по моему опыту, он работает нормально, мой вопрос: если это вопрос времени, и он опасен и может привести к аварии по какой-либо причине, или это абсолютно безопасно и просто приятно иметь правило?

1 ответ

Решение

TL;DR - всегда маршал... всегда.

Зачем? COM знает об этом и будет делать правильные вещи...

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

Да. Всегда.

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

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

... если COM-класс является потокобезопасным, то есть он помечен как Both или Free...

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

Судя по моему опыту, он работает нормально, мой вопрос: если это вопрос времени, опасен и приводит к краху по какой-либо причине, или это абсолютно безопасно и просто приятно иметь правило?

Подрыв потоковой модели COM обычно приводит к слезам - возможно, через несколько лет после первоначального нарушения. Это бомба замедленного действия. Не делай этого.


Как отмечено в комментариях, есть CoCreateFreeThreadedMarshaler, но, как упомянуто в примечаниях в связанной документации, он требует "... расчетного нарушения правил COM..." и намекает на необщую или узкую полосу применимости.

Другие вопросы по тегам