У меня есть управляемый объект, который вызывает COM-сервер для выделения некоторой памяти. Управляемый объект должен снова вызвать COM-сервер, чтобы освободить эту память, прежде чем управляемый объект уйдет, чтобы избежать утечки памяти. Этот объект реализует IDisposable
, чтобы гарантировать выполнение правильного освобождающего память COM-вызова.
В случае, если метод Dispose
не вызван, я бы хотел, чтобы финализатор объекта освободил память. Проблема в том, что правила финализации заключаются в том, что вы не должны обращаться к какой-либо ссылке, потому что вы не знаете, какие другие объекты уже были GC'd и / или финализированы до вас. При этом единственным доступным для прикосновения состоянием объекта остаются поля (наиболее распространены дескрипторы).
Но вызов COM-сервера включает прохождение вызываемой оболочки времени выполнения (RCW), чтобы освободить память, в которой у меня есть файл cookie, который хранится в поле. Безопасно ли вызывать этот RCW из финализатора (гарантируется ли, что на этом этапе он не был GC'd или финализирован)?
Для тех из вас, кто не знаком с финализацией, хотя поток финализатора работает в фоновом режиме управляемого домена приложения во время его работы, в этих случаях касание ссылок теоретически будет нормально, финализация также происходит при выключении домена приложения и в любом порядке - не только в порядке ссылочных отношений. Это ограничивает то, к чему вы можете безопасно прикасаться из финализатора. Любая ссылка на управляемый объект может быть «плохой» (собранная память), даже если ссылка не равна нулю.
Обновление: я только что попробовал и получил следующее:
Необработанное исключение типа System.Runtime.InteropServices.InvalidComObjectException произошло в myassembly.dll
Дополнительная информация: COM-объект, который был отделен от лежащего в его основе RCW, использовать нельзя.