При использовании COM из неуправляемого кода (C / C ++) правила довольно строги: вы можете вызывать методы только на интерфейсе из той же квартиры, на которой вы приобрели объект. Таким образом, если вы получите указатель на интерфейс в потоке STA, то только этому потоку разрешено вызывать любой из методов. Если вы получите указатель на интерфейс в потоке MTA, то этот указатель могут использовать только другие потоки в том же MTA. Любое другое использование, которое пересекает квартиры, требует, чтобы указатель интерфейса был перенесен в другую квартиру.
Тем не менее, это мир без изменений. .Net добавляет целый слой поверх COM, который скрывает много этих низкоуровневых деталей, и по большей части, как только вы получите интерфейс, вы можете передавать этот интерфейс между потоками столько, сколько пожелаете, без приходится беспокоиться о старых правилах потоков. Здесь происходит то, что он фактически передает ссылки на объект, называемый «Runtime Callable Wrapper» (RCW), и управляет базовым интерфейсом COM и соответствующим образом контролирует доступ к нему. (Это берет на себя бремя поддержки правил COM-квартиры, так что вам не нужно, и поэтому может показаться, что старые правила COM-потоков не применяются в .Net: они есть, они просто скрыты от вы.)
Таким образом, вы можете безопасно вызывать Release или другие методы из другого потока: но имейте в виду, что если исходный поток был STA, то вызов этих методов приведет к тому, что базовый RCW перенаправит вызов обратно в исходный поток-владелец, чтобы он все еще поддерживает подчиненные правила COM. Таким образом, использование отдельного потока может на самом деле не дать вам никакой производительности!
Некоторые статьи, достойные прочтения, которые заполняют некоторые детали здесь: