tengo un Excel plug-in (escrito en C#) con una variable estática que está en el corazón de un caché de datos Singleton:¿Excel invoca al servidor de automatización .NET desde dos AppDomains diferentes?
static DataCache _instance;
Esto se accede a través de tres diferentes rutas de código:
- Controladores de eventos en una barra de cinta VSTO inicializan la instancia y también la leen en los cuadros de diálogo auxiliares
- Un servidor RTD (una clase declarada [ComVisible] e implementa la interfaz IRtdServer) utiliza los datos para las fórmulas RTD
- Un conjunto de llamadas de automatización (implementadas en otra clase que se declara [ComVisible]) también operan en los datos. Se llaman a través de un código VBA que se invoca cuando se hace clic en los botones de la hoja de cálculo de Excel.
EDITAR (# 3):
En función del orden en que estas rutas de código se invocan en primer lugar, me parece que mi código se ejecuta en dos dominios de aplicación separados.
Todos los accesos desde los controladores de eventos de barra de cinta se producen en un dominio de aplicación llamado "MyPlugIn.vsto". Si este es el PRIMER acceso a mi objeto COM, todas las llamadas posteriores (incluidas las llamadas RTD) se producen en el mismo dominio de la aplicación.
Sin embargo, si el acceso FIRST es a través de la interfaz RTD, entonces esa llamada y todas las llamadas posteriores de RTD se producen en un dominio de aplicación llamado "DefaultDomain". (Esto ocurre cuando se carga un documento guardado con fórmulas RTD incorporadas). Las llamadas posteriores para inicializar y manipular el DataCache a través de la barra de herramientas todavía ocurren en el Dominio de aplicación "MyPlugIn.vsto". Esto significa que las fórmulas de RTD siempre se ejecutan como si DataCache no se hubiera inicializado (dado que la variable estática establecida en un AppDomain permanece sin inicializar en el otro).
Parece que Excel o VSTO está creando un dominio de aplicación cuando se inicializa VSTO. Los objetos creados a través de interoperabilidad COM antes de aterrizar esta inicialización en el AppDomain predeterminado, mientras que los objetos creados posteriormente aterrizan en el AppDomain de VSTO.
¿Cómo puedo asegurarme de que se utiliza la misma instancia de DataCache, sin importar en qué dominio de aplicación se crea mi objeto de servidor RTD?
¿Qué quiere decir 'mi objeto singleton no se comparte correctamente'? ¿Es solo la inicialización del objeto, como lo sugiere @mhttk, o está afirmando que diferentes hilos ven diferente estado en esa variable (lo que parece muy extraño), o algo más? – Rory
@Rory - en un hilo, _instance se inicializa. En llamadas posteriores de ese mismo hilo, todavía se inicializa como se esperaba. Sin embargo, cuando otro hilo intenta acceder a él (varios minutos más tarde, esto no es un problema de tiempo) es nulo y debe ser reinicializado para que lo use ese hilo. – Eric
Eso es bastante raro ¿no? En mi experiencia de.NET COM interopera (con Internet Explorer que es similar pero obviamente diferente), eso no sucede. ¿Es eso algo normal con los apartamentos COM? ¿Estás seguro de que las llamadas están dentro del mismo proceso? – Rory