COM-объект, который был отделен от базового RCW, не может быть использован - PullRequest
43 голосов
/ 14 февраля 2010

У меня есть какой-то компонент COM, который я вызываю из некоторого c # dll.

У меня также есть приложение winforms, которое использует .dll.

Когда я закрываю приложение, я получаю следующее исключение:

COM-объект, который был отделен из лежащего в его основе RCW нельзя б.

Трассировка стека показывает, что это исключение происходит от деструктора в .dll. Я реализовал этот деструктор для вызова некоторого метода очистки в COM.

Почему это происходит? Как это лучше всего решить?

1 Ответ

33 голосов
/ 14 февраля 2010

Проблема описана здесь:

Безопасно ли вызывать RCW из финализатора?

и здесь:

Освобождение объекта Excel в моем деструкторе

Беда в том, что не только время, когда эти объекты должны быть мусора неясным, но порядок, в котором финализаторы называются также недетерминированными. В этом случае Runtime Callable Wrapper также имеет финализатор, который вызывает Marshal.FinalReleaseComObject на себя, который имеет результат уменьшая счетчик ссылок на стороне COM ограждения, чтобы этот COM-объект может быть освобожден. Но так как порядок, в котором финализаторы называются неопределенным, очень возможно, что финализаторы для объектов COM, которые будут ссылаться на ваши объекты перед финализатором для вашего объекта. Так что код в вашем финализатор может иногда работать, но, в большинстве случаев, один или несколько исполняемые Callable Wrappers, которые будут иметь ссылки на ваш объект уже были вызваны их финализаторы и базовый COM-объект были освобождены до того, как ваш финализатор выполнит свой код.

...