Был ли COM-объект отделен от своего RCW?
Я пытаюсь исправить проблему с ошибкой "COM-объект, который был отделен от лежащего в его основе RCW, невозможно", и я думаю, что причина в том, что COM-объекты используются в потоке, который их не создавал.
Мне не разрешают много заниматься рефакторингом, и поскольку объекты должны быть доступны в нескольких потоках, мне интересно, есть ли способ узнать, были ли они созданы в текущем потоке, прежде чем делать с ними что-то, что могло бы вызвать вышеупомянутую ошибку. И, если они этого не сделали, создайте их.
Кроме того, я новичок в этом взаимодействии, поэтому, если кто-то будет достаточно любезен, чтобы помочь мне понять, я буду очень признателен:
Что происходит с COM-объектом после завершения потока и почему RCW по-прежнему доступен в другом потоке, даже если в нем больше нет COM-объекта (почему он не является нулевым?). Кроме того, почему это вызвало бы эту ошибку и в то же время вернуло true на Marshal.IsCOMObject?
Что происходит в следующих сценариях с количеством ссылок, оберткой и памятью:
- Создать COM-объект x в потоке A
- Передайте это и сохраните это на нити B
- Создайте еще один x (альтернативно, что произойдет, если это будет y?) В потоке C
- Передайте его и перезапишите x в потоке B
1 ответ
Что происходит с COM-объектом после завершения потока
COM-объект автоматически уничтожается COM. Который будет генерировать сообщение об исключении "COM-объект, который был отделен", когда другой поток продолжает его использовать. Вы не можете позволить потоку выйти.
Очевидно, у вас есть однопоточный COM-сервер, безусловно, самый распространенный тип. Он связан с потоком STA, на котором он был создан. COM гарантирует, что все вызовы, сделанные в другом потоке, автоматически направляются в поток, создавший объект. Это больше не может работать, когда поток ушел. Также будьте осторожны, что вы не получите параллелизма.
Другой способ получить это исключение - сделать ошибку обработки явного количества ссылок с помощью Marshal.ReleaseComObject(). Также не исключено, что вы должны были получить предупреждение MDA.