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