Ho un Excel plug-in (scritto in C#) con una variabile statica che è al centro di una cache di dati Singleton:Excel richiama il server di automazione .NET da due diversi AppDomain?
static DataCache _instance;
Questo si accede tramite tre diversi percorsi di codice:
- I gestori di eventi su barra a nastro VSTO inizializzano l'istanza e la leggono per la visualizzazione nelle finestre di dialogo di supporto
- Un server RTD (una classe dichiarata [ComVisible] e implementa l'interfaccia IRtdServer) utilizza i dati per le formule di RTD
- Un insieme di chiamate di automazione (implementate in un'altra classe dichiarata [ComVisible]) operano anche sui dati. Questi sono chiamati tramite codice VBA che viene richiamato quando si fa clic sui pulsanti nel foglio di lavoro di Excel.
EDIT (# 3):
A seconda dell'ordine in cui questi percorsi di codice vengono prima richiamati, trovo che il mio codice viene eseguito in due AppDomain separati.
Tutti gli accessi dai gestori di eventi barra a nastro si verificano in un AppDomain denominato "MyPlugIn.vsto". Se questo è il primo accesso al mio oggetto COM, tutte le chiamate successive (incluse le chiamate RTD) si verificano nello stesso AppDomain.
Tuttavia, se il primo accesso avviene tramite l'interfaccia RTD, la chiamata e tutte le chiamate RTD successive si verificano in un AppDomain denominato "DefaultDomain". (Questo accade quando si carica un documento salvato con formule RTD incorporate.) Le chiamate successive per inizializzare e manipolare DataCache tramite la barra degli strumenti si verificano ancora nell'AppDomain "MyPlugIn.vsto". Ciò significa che le formule di RST vengono sempre eseguite come se DataCache non fosse inizializzato (poiché la variabile statica impostata in un AppDomain non è inizializzata nell'altro).
Sembra che Excel o VSTO stiano creando un AppDomain quando VSTO viene inizializzato. Gli oggetti creati tramite interoperabilità COM prima di questo campo di inizializzazione nell'AppDomain predefinito, mentre gli oggetti creati successivamente vengono inseriti nell'AppDomain VSTO.
Come posso garantire che la stessa istanza DataCache viene utilizzato, non importa quale dominio di applicazione il mio oggetto server RTD viene creato in?
Cosa intendi per "il mio oggetto singleton non è correttamente condiviso"? È solo l'inizializzazione dell'oggetto, come suggerisce @mhttk, o stai affermando che thread diversi vedono diversi stati in quella variabile (che sembra molto strana), o qualcos'altro? – Rory
@Rory - in un thread, _instance viene inizializzata. Nelle chiamate successive da quello stesso thread, è ancora inizializzato come previsto. Tuttavia, quando un altro thread tenta di accedervi (alcuni minuti più tardi - questo non è un problema di temporizzazione) è nullo e deve essere reinizializzato per essere utilizzato da quel thread. – Eric
È piuttosto strano, vero? Nella mia esperienza di.Interop NET COM (con Internet Explorer che è simile ma ovviamente diverso), ciò non accade. È una cosa normale con gli appartamenti COM? Sei sicuro che le chiamate siano all'interno dello stesso processo? – Rory