У меня есть подключаемый модуль Excel (написанный на C #) со статической переменной, которая лежит в основе кэша одноэлементных данных:
static DataCache _instance;
Доступ к нему осуществляется через три разных пути кода:
- Обработчики событий на ленточной панели VSTO инициализируют экземпляр, а также читают его для отображения во вспомогательных диалоговых окнах.
- Сервер RTD (класс, который объявлен [ComVisible] и реализует интерфейс IRtdServer) использует данные для формул RTD.
- Набор вызовов автоматизации (реализованных в другом классе, объявленном [ComVisible]) также работает с данными. Они вызываются с помощью кода VBA, который вызывается при нажатии кнопок на листе Excel.
РЕДАКТИРОВАТЬ (# 3):
В зависимости от порядка, в котором эти пути кода сначала вызываются, я обнаружил, что мой код выполняется в двух отдельных доменах приложений.
Весь доступ из обработчиков событий ленты происходит в домене приложений под названием «MyPlugIn.vsto». Если это ПЕРВЫЙ доступ к моему COM-объекту, то все последующие вызовы (включая вызовы RTD) происходят в том же домене приложений.
Однако если ПЕРВЫЙ доступ осуществляется через интерфейс RTD, то этот вызов и все последующие вызовы RTD происходят в домене приложения, называемом «DefaultDomain». (Это происходит при загрузке сохраненного документа со встроенными формулами RTD.) Последующие вызовы для инициализации и управления DataCache через панель инструментов по-прежнему происходят в домене приложения «MyPlugIn.vsto». Это означает, что формулы RTD всегда выполняются так, как если бы DataCache не был инициализирован (поскольку статическая переменная, установленная в одном домене приложения, остается неинициализированной в другом).
Похоже, что Excel или VSTO создают домен приложения при инициализации VSTO. Объекты, созданные через COM-взаимодействие до этой инициализации, попадают в домен приложений по умолчанию, а объекты, созданные после этого, попадают в домен приложений VSTO.
Как я могу гарантировать, что используется один и тот же экземпляр DataCache, независимо от того, в каком домене приложения создается мой объект сервера RTD?
Process.GetCurrentProcess().Id
иThread.GetDomainId()
в отладчике, чтобы увидеть, поступают ли вызовы в один и тот же процесс и домен приложения. И напишите сообщение в DataCache.Dispose (), чтобы вы могли видеть, когда оно удалено. - person Rory   schedule 25.10.2010