Вопрос

Действительно ли необходимо выпускать компоненты COM из Office PIA, когда они вам больше не нужны, вызывая Marshal.ReleaseComObject (..)?

Я нашел в Интернете различные и противоречивые советы по этой теме. По моему мнению, поскольку Outlook PIA всегда возвращает новые ссылки на свои интерфейсы как возвращающие значения из своих методов, нет необходимости явно освобождать его. Я прав?

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

Решение

В целом, в Microsoft Office вам необходимо явно опубликовать свои ссылки, что можно безопасно сделать в два этапа:

(1) Сначала освободите все второстепенные объекты, для которых вы не храните именованную переменную объекта, с помощью вызова GC.Collect (), а затем GC.WaitForPendingFinalizers (). (Вам нужно вызывать это дважды, если участвующие объекты могут иметь финализаторы, например, при использовании Visual Studio Tools for Office (VSTO).)

(2) Затем явным образом освободите объекты, для которых вы храните именованную переменную, с помощью вызова Marshall.FinalReleaseComObject () для каждого объекта.

Вот и все. : -)

Я обсуждал это более подробно в предыдущий пост вместе с примером кода.

Другие советы

PIA - это оболочки взаимодействия .NET. Это означает, что в деструкторе объекта (или Dispose - я не помню) будет автоматически обрабатывать его счетчик ссылок. Хитрость в том, что некоторые ссылки не будут освобождены, пока не будет выполнен сборщик мусора. Это зависит от того, что создает объект COM. Например, COM-объект, открывающий курсоры базы данных, будет поддерживать эти курсоры в памяти до тех пор, пока счетчик ссылок на эти курсоры не будет освобожден. При взаимодействии .NET / COM ссылки не освобождаются до тех пор, пока не выполнится сборщик мусора или вы не освободите ссылку явно с помощью Marshal.ReleaseComObject (или FinalReleaseComObject).

Лично я не работал с PIA Microsoft Office, но в большинстве случаев вам не нужно иметь для явного освобождения ссылок. Только когда ваше приложение начинает блокировать другие ресурсы или происходит сбой, вы должны начать подозревать висячие ссылки.

РЕДАКТИРОВАТЬ: Если вы столкнулись с ситуацией, когда вам нужно очистить объекты COM / Interop, используйте Marshal.FinalReleaseComObject - который переводит счетчик ссылок в ноль, а не просто уменьшает его на единицу. - и установите ссылку на объект на ноль. Вы можете явно принудительно выполнить сборку мусора (GC.Collect), если вы действительно хотите быть в безопасности, но будьте осторожны с выполнением GC слишком часто, так как это вызывает заметное снижение производительности.

Здесь есть несколько полезных советов с использованием управляемой оболочки… проверяя ..

Возможно, это просто мое суеверие, но я решил явно выпустить Office PIA через Marshal.ReleaseComObject (), потому что когда мое приложение зависало, ссылки на Excel и Word оставались открытыми. Я не слишком углублялся в причину (глупые сроки), но выпуская их как часть шаблона распоряжения моего класса, решил эту проблему.

Это необходимо сделать, если вы хотите, чтобы экземпляр приложения Office завершился, как описано в это сообщение .

И это трудно сделать правильно во всех случаях, кроме самых простых.

Существует одно простое правило о взаимодействии .Net / COM - если есть сомнения, всегда Release (). : -)

Мой опыт показывает, что это необходимо, иначе (по крайней мере, Outlook) приложение может вообще не закрыться.

Но это открывает еще одну банку червей, так как похоже, что RCW для каждого процесса, поэтому вы можете сломать какой-то другой плагин, который имеет ссылку на тот же объект.

Я разместил соответствующий вопрос здесь , но у меня до сих пор нет четкого ответа. Я буду редактировать этот пост, когда узнаю больше.

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