Когда среда выполнения .NET сохраняет счетчик ссылок > 1 для COM-объектов?

StackOverflow https://stackoverflow.com/questions/2567236

  •  24-09-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top