Когда среда выполнения .NET содержит счетчик ссылок> 1 для объектов COM? - PullRequest
6 голосов
/ 02 апреля 2010

До недавнего времени я считал, что среда выполнения .NET увеличивает счетчик ссылок COM-объектов только на 1 при создании оболочки, вызываемой во время выполнения , и что только одна такая среда, вызываемая во время выполнения, создается для любого данный COM-объект.

Если я не ошибаюсь, из вышесказанного следует, что Marshal.FinalReleaseComObject и Marshal.ReleaseComObject делают то же самое на практике.

Однако сегодня я писал несколько тестов для проверки правильности освобождения COM-объектов моим кодом. Я делаю это, вызывая предположительно освобожденный объект и проверяя ожидаемый InvalidComObjectException. Оказывается, есть случаи, когда исключение выдается после FinalReleaseComObject, но не после ReleaseComObject.

Значит ли это, что среда выполнения .NET 2.0 может содержать более одной ссылки на COM-объект? Если да, то когда это происходит?

1 Ответ

5 голосов
/ 02 апреля 2010

Здесь есть дополнительный уровень косвенности. Да, RCW ведет единый подсчет ссылок на родных указателях интерфейса COM. Но у RCW также есть счетчик ссылок, он увеличивается каждый раз, когда указатель COM-интерфейса отображается на RCW. Что может произойти, если метод COM возвращает указатель на интерфейс. Финализатор соответствующего класса-оболочки .NET уменьшает его.

Вы можете возиться с этим счетчиком ссылок непосредственно через Marshal.ReleaseComObject (), который уменьшает его на единицу, как это делает финализатор, и Marshal.FinalReleaseComObject (), который обнуляет его, гарантируя, что IUnknown :: Release () метод называется. Они, конечно, попадают в категорию «лучше знать, что ты делаешь». Неправильное и некорректное создание «COM-объекта, отделенного от лежащего в его основе RCW», исключение.

...