Domanda

Qual è l'ambito di Runtime Callable Wrapper (RCW), quando si fa riferimento a oggetti COM non gestiti? Secondo i documenti:

  

Il runtime crea esattamente un RCW   per ogni oggetto COM, indipendentemente da   numero di riferimenti esistenti su   quell'oggetto.

Se dovessi "indovinare" - questa spiegazione dovrebbe significare "uno per processo", ma è davvero? Qualsiasi ulteriore documentazione sarà molto gradita.

La mia applicazione viene eseguita nel suo dominio di applicazione (è il componente aggiuntivo di Outlook) e vorrei sapere cosa succede se uso Marshal.ReleaseComObject (x) in un ciclo fino a quando il conteggio raggiunge 0 (come consigliato). Rilascerà riferimenti da altri componenti aggiuntivi (in esecuzione in un altro dominio dell'applicazione nello stesso processo di Outlook)?

EDIT: perfetto - ora la confusione è ancora più grande. Sulla base delle 2 risposte (di Lette e Ilya) abbiamo 2 risposte diverse. Il MSDN doc ufficiale dice per processo (per versione 2.0+), ma manca questa frase per ver. 1.1 del documento .

Allo stesso tempo, nell'articolo di Mason Bendixen, dice che è per dominio.

Dato che il suo articolo è vecchio (aprile 2007), gli ho inviato un'e-mail per chiedere chiarimenti, ma se qualcun altro deve aggiungere qualcosa, per favore fallo.

Grazie

È stato utile?

Soluzione

  

In gestito, abbiamo un dominio per app   nascondiglio   mappatura di IUnnowns canonici a   RCWs. Quando un IUnnown entra in   sistema (tramite un richiamo del maresciallo,   attraverso l'attivazione, come ritorno   parametro da una chiamata di metodo, ecc.),   controlliamo la cache per vedere se un RCW   esiste già per l'oggetto COM. Se   esiste una mappatura, un riferimento a   viene restituito RCW esistente. Altrimenti a   viene creato un nuovo RCW e una mappatura della cache   è stato aggiunto.

da Blog di Mason

Altri suggerimenti

L'articolo del blog Mason Bendixen che Ilya cita è corretto: l'RCW è mirato all'AppDomain, non al processo. Posso solo supporre che il Wrapper di runtime Callable (MSDN 2.0) l'articolo parlava "casualmente". Tale articolo non è necessariamente errato in senso generale, poiché è più tipico eseguire solo un singolo AppDomain, ma quella frase non è tecnicamente accurata.

Per quanto riguarda la tua domanda specifica:

  

" Vorrei sapere cosa succede se   usa Marshal.ReleaseComObject (x) in a   ciclo fino a quando il conteggio raggiunge 0 (come   consigliato). Rilascerà   riferimenti da altri componenti aggiuntivi   (in esecuzione in un altro dominio dell'applicazione   nello stesso processo di Outlook) ?? "

La risposta dipende da come hai impostato il componente aggiuntivo. In generale, se non si prendono precauzioni, la risposta è sì, avrebbe un impatto sui riferimenti in altri componenti aggiuntivi che operano all'interno dello stesso AppDomain. Ma poiché dichiari di essere in esecuzione da un AppDomain separato, allora no, non lo farebbe.

Esiste un COM Shim Procedura guidata versione 2.3.1 che è possibile utilizzare per isolare il componente aggiuntivo. La documentazione per lo Shim Wizard COM è disponibile qui: Isolamento delle estensioni di Microsoft Office con il COM Shim Wizard Versione 2.3.1 .

La procedura guidata shim COM utilizza la reflection per creare un caricatore front-end COM personalizzato che carica l'assembly del componente aggiuntivo in un AppDomain separato. Ciò crea sicurezza sotto due aspetti:

(1) Utilizzando un punto di ingresso COM personalizzato e separato, il componente aggiuntivo viene identificato correttamente separatamente da Microsoft Office da tutti gli altri componenti aggiuntivi. Altrimenti, per impostazione predefinita, tutti i componenti aggiuntivi condividono lo stesso caricatore mscoree.dll predefinito. Il problema con la condivisione dello stesso caricatore è che se un componente aggiuntivo presenta un arresto anomalo, allora mscoree.dll verrà identificato da Microsoft Office come fonte del problema e non lo caricherà automaticamente la volta successiva. Puoi riaccenderlo manualmente, ma il componente aggiuntivo non verrà caricato automaticamente la volta successiva a causa di un problema nel componente aggiuntivo di qualcun altro!

(2) Caricando il proprio assieme in un AppDomain separato, i wrapper richiamabili di runtime (RCW) vengono isolati dagli altri componenti aggiuntivi caricati nello stesso processo. In questo caso, se chiami Marshal.ReleaseComObject (oggetto) o Marshal.FinalReleaseComObject (oggetto), non influenzeresti i componenti aggiuntivi di nessun altro. Ancora più importante, se uno di questi altri componenti aggiuntivi effettua tali chiamate, il componente aggiuntivo sarebbe protetto dalla corruzione. : -)

Il rovescio della medaglia nell'uso della COM Shim Wizard è che operando da un AppDomain separato c'è un sovraccarico di marshalling aggiuntivo. Non credo che questo dovrebbe essere evidente per un componente aggiuntivo di Microsoft Outlook. Può essere un fattore, tuttavia, per alcune routine intensive che hanno molte chiamate al modello a oggetti, come talvolta può essere il caso di un componente aggiuntivo di Microsoft Excel.

Hai dichiarato che stai già eseguendo il componente aggiuntivo da un AppDomain separato. Se questo è vero, allora sei già isolato dalle chiamate Marshal.ReleaseComObject (oggetto) e Marshal.FinalReleaseComObject (oggetto) rispetto ad altri AppDomain. (Sono curioso di sapere come lo stai facendo, tra l'altro ... Stai creando esplicitamente il tuo AppDomain? Il modello di componente aggiuntivo predefinito in Visual Studio non viene eseguito in AppDomain separato e carica utilizzando il mscoree.dll.)

Se stai creando il tuo AppDomain, il tuo codice è isolato, ma la sua identità potrebbe non essere separata da altri componenti aggiuntivi, tuttavia, poiché il tuo componente aggiuntivo condividerebbe ancora il caricatore mscoree.dll predefinito, a meno che tu non lo utilizzassi alcuni altri mezzi per affrontarlo.

Spero che questo aiuti ...

Secondo gli stessi documenti:

  

Il runtime mantiene un singolo RCW per processo per ciascun oggetto.

Penso che possiamo tranquillamente presumere che oggetto = istanza , quindi se gli addin / AppDomains non contengono riferimenti alla stessa istanza, la chiamata a ReleaseComObject non rilascerà riferimenti a istanze create altrove.

Modifica: il testo dei documenti potrebbe essere sbagliato, come indicato altrove . In tal caso, poiché il componente aggiuntivo è in esecuzione in un AppDomain separato, sei fortunato. Anche se i diversi componenti aggiuntivi fanno riferimento alla stessa istanza (ad esempio un oggetto Message in Outlook), ReleaseComObject chiamato in AppDomain non farà perdere ai riferimenti RCW in altri AppDomain il riferimento a tale istanza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top