Был ли COM-объект отделен от своего RCW? - PullRequest
2 голосов
/ 05 апреля 2011

Я пытаюсь исправить проблему с ошибкой «COM-объект, который был отделен от лежащего в его основе RCW, невозможно», и я думаю, что причина в том, что COM-объекты используются в потоке, который их не создавал.

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

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

Что происходит с COM-объектом после завершения потока, и почему RCW по-прежнему доступен в другом потоке, даже если в нем больше нет COM-объекта (почему он не нулевой?). Кроме того, почему это вызвало бы эту ошибку и в то же время вернуло значение true на Marshal.IsCOMObject?

Что происходит в следующих сценариях с количеством ссылок, оберткой и памятью:

  • Создать COM-объект x в потоке A
  • Передайте его и сохраните в потоке B
  • Создайте еще один x (альтернативно, что бы произошло, если бы это был y?) В потоке C
  • Передайте его и перезапишите x в потоке B

1 Ответ

4 голосов
/ 05 апреля 2011

Что происходит с COM-объектом после завершения потока

COM-объект автоматически уничтожается COM. Который выдаст сообщение об исключении «COM-объект, который был отделен», когда другой поток продолжает его использовать. Вы не можете позволить потоку выйти.

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

Еще один способ получить это исключение - сделать ошибку обработки явного подсчета ссылок с помощью Marshal.ReleaseComObject (). Также не исключено, что вы должны были получить предупреждение MDA.

...