Область действия вызываемой оболочки во время выполнения (RCW) - область процесса или приложения? - PullRequest
6 голосов
/ 01 октября 2008

Какова область действия Runtime Callable Wrapper (RCW) при обращении к неуправляемым COM-объектам? По документам:

Среда выполнения создает ровно один RCW для каждого COM-объекта, независимо от количество ссылок, которые существуют на этот объект.

Если бы мне пришлось «угадать» - это объяснение должно означать «по одному на процесс», но так ли это на самом деле? Любая дополнительная документация будет приветствоваться.

Мое приложение работает в своем собственном домене приложений (это надстройка для Outlook), и я хотел бы знать, что произойдет, если я использую Marshal.ReleaseComObject (x) в цикле, пока его число не достигнет 0 (как рекомендуется). Выпустит ли он ссылки из других надстроек (работающих в другом домене приложения в том же процессе Outlook)?

РЕДАКТИРОВАТЬ: Отлично - теперь путаница еще больше. На основе 2 ответов (от Lette и Ilya) у нас есть 2 разных ответа. Официальный документ MSDN говорит за процесс (для версии 2.0+), но пропускает это предложение для версии. 1.1 документа .

В то же время в статье Мэйсона Бендиксена говорится, что это для домена приложения.

Поскольку его статья старая (апрель 2007 г.), я отправил ему электронное письмо с просьбой дать разъяснения, но если кому-то еще нужно что-то добавить, пожалуйста, сделайте.

Спасибо

Ответы [ 3 ]

3 голосов
/ 02 октября 2008

В управляемом у нас есть домен для приложения кэш отображение канонических IUnknowns обратно в RCWS. Когда IUnknown входит в система (через вызов маршала, через активацию, как возврат параметр из вызова метода и т. д.), мы проверяем кеш, чтобы увидеть, если RCW уже существует для объекта COM. Если существует сопоставление, ссылка на существующий RCW возвращается. В противном случае новый RCW создан и отображение кеша добавлено.

из Блог Мейсона

3 голосов
/ 04 октября 2008

Статья в блоге Мейсона Бендиксена, которую Илья цитирует, верна: RCW относится к домену приложений, а не к процессу. Я могу только догадываться, что статья Runtime Callable Wrapper (MSDN 2.0) говорила «случайно». Эта статья не обязательно неверна в общем смысле, потому что ее наиболее типично выполнить с использованием только одного домена приложений, но это предложение не является технически точным.

Что касается вашего конкретного вопроса:

«Я хотел бы знать, что произойдет, если я используйте Marshal.ReleaseComObject (x) в цикл, пока его счетчик не достигнет 0 (как рекомендуемые). Это выпустит ссылки из других дополнений (работает в другом домене приложения в том же процессе Outlook) ?? "

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

Существует COM Shim Wizard версии 2.3.1 , который вы можете использовать для изоляции вашей надстройки. Документацию по мастеру COM Shim можно найти здесь: Изоляция расширений Microsoft Office с помощью мастера COM Shim версии 2.3.1 .

Мастер COM Shim Wizard использует отражение для создания настроенного фронтального загрузчика COM, который загружает сборку надстройки в отдельный домен приложения. Это создает безопасность в двух отношениях:

(1) Используя отдельную настроенную точку входа COM, ваша надстройка корректно идентифицируется Microsoft Office отдельно от всех других надстроек. В противном случае по умолчанию все надстройки имеют общий загрузчик mscoree.dll по умолчанию. Проблема с совместным использованием одного и того же загрузчика заключается в том, что в случае сбоя какой-либо надстройки Microsoft Office определит mscoree.dll как источник проблемы и не загрузит ее автоматически в следующий раз. Вы можете включить его снова вручную, но ваша надстройка не загрузится автоматически в следующий раз из-за проблемы в чужой надстройке!

(2) При загрузке вашей сборки в отдельном домене приложений вызываемые оболочки времени выполнения (RCW) изолируются от других надстроек, загружаемых в тот же процесс. В этом случае, если вы вызовете Marshal.ReleaseComObject (object) или Marshal.FinalReleaseComObject (object), вы не будете влиять на чужие надстройки. Что еще более важно, если какие-либо другие надстройки совершают такие вызовы, ваша надстройка будет защищена от повреждения. : -)

Недостатком использования COM Shim Wizard является то, что при работе с отдельным доменом приложений возникают дополнительные издержки на сортировку. Я не верю, что это должно быть заметно для надстройки Microsoft Outlook. Однако это может быть важным фактором для некоторых интенсивных подпрограмм, которые имеют много вызовов объектной модели, например, иногда для надстройки Microsoft Excel.

Вы заявили, что уже запускаете надстройку из отдельного домена приложений. Если это так, то вы уже изолированы от вызовов Marshal.ReleaseComObject (объект) и Marshal.FinalReleaseComObject (объект) относительно других доменов приложений. (Кстати, мне интересно, как вы это делаете ... Вы явно создаете свой собственный домен приложений? Шаблон надстройки по умолчанию в Visual Studio не запускается в отдельном домене приложений и загружается с использованием mscoree.dll.)

Если вы создаете свой собственный домен приложений, ваш код изолирован, но его идентификация может не отличаться от других надстроек, поскольку ваша надстройка все еще будет использовать загрузчик по умолчанию mscoree.dll, если вы не использовали другие способы решения этой проблемы.

Надеюсь, это поможет ...

1 голос
/ 02 октября 2008

По тем же документам:

Среда выполнения поддерживает один RCW на процесс для каждого объекта.

Я думаю, мы можем с уверенностью предположить, что объект = экземпляр , поэтому, если addins / AppDomains не содержит ссылок на тот же экземпляр, вызов ReleaseComObject выиграл ' t выпускать ссылки на экземпляры, созданные в других местах.

Редактировать: формулировка документов может быть неправильной, , как указано в другом месте . Если так, то ваша надстройка работает в отдельном домене приложений, вам повезло. Даже если разные надстройки ссылаются на один и тот же экземпляр (например, объект сообщения в Outlook), ReleaseComObject, вызываемый в вашем домене приложений, не приведет к тому, что RCW в других доменах приложений потеряют ссылку на этот экземпляр.

...