2008-10-01 9 views
6

Welchen Umfang hat der Runtime Callable Wrapper (RCW), wenn er auf nicht verwaltete COM-Objekte verweist? Nach der Dokumentation:Runtime Callable Wrapper (RCW) Anwendungsbereich - Prozess oder Anwendungsdomäne?

Die Laufzeit erstellt genau ein RCW für jedes COM-Objekt, und zwar unabhängig von der Anzahl der Referenzen, die auf existieren das Objekt.

Wenn ich "raten" müsste - diese Erklärung sollte "einen pro Prozess" bedeuten, aber ist es wirklich? Jede zusätzliche Dokumentation ist sehr willkommen.

Meine Anwendung läuft in einer eigenen Anwendungsdomäne (es ist Outlook-Addin), und ich würde gerne wissen, was passiert, wenn ich Marshal.ReleaseComObject (x) in einer Schleife verwenden, bis die Zählung 0 erreicht (wie empfohlen). Wird es Referenzen von anderen Addins freigeben (die in einer anderen Anwendungsdomäne im selben Outlook-Prozess ausgeführt werden)?

EDIT: Perfekt - jetzt ist die Verwirrung noch größer. Basierend auf den 2 Antworten (von Lette und Ilya) haben wir 2 verschiedene Antworten. Der offizielle MSDN doc sagt pro Prozess (für ver. 2.0+), aber es fehlt dieser Satz für ver. 1.1 of the doc.

In der gleichen Zeit, in Mason Bendixens Artikel, heißt es, es ist pro appdomain.

Da sein Artikel alt ist (April 2007), habe ich ihm eine E-Mail mit der Bitte um Klärung geschickt, aber wenn jemand anderes etwas hinzufügen muss, tun Sie es bitte.

Dank

Antwort

3

In verwalteten, haben wir eine pro Anwendungsdomäne Cache Mapping kanonische IUnknowns zurück zu RCWs. Wenn ein IUnknown das -System (durch einen Marshal-Aufruf, durch Aktivierung, als Rückgabewert Parameter von einem Methodenaufruf usw.), eingeben, überprüfen wir den Cache, um zu sehen, ob ein RCW bereits für das COM-Objekt vorhanden ist. Wenn ein Mapping vorhanden ist, wird ein Verweis auf den vorhandenen RCW zurückgegeben. Andernfalls wird ein neuer RCW erstellt und ein Cache-Mapping hinzugefügt.

von Mason's Blog

1

denselben Dokumenten Laut:

Die Laufzeit eines einzelnen RCW pro Prozess hält für jedes Objekt.

ich denke, wir können sicher davon ausgehen, dass Objekt = Instanz, also, wenn das Add-In/AppDomains keine Verweise halten, um die gleichen Instanz, der Aufruf an ReleaseComObject nicht Verweisen auf Instanzen freigeben anderswo erstellt .

Edit: Der Wortlaut der Dokumente möglicherweise falsch, as stated elsewhere. Wenn dies der Fall ist, haben Sie Glück, da Ihr Add-In in einer separaten AppDomain ausgeführt wird. Selbst wenn die verschiedenen Add-Ins dieselbe Instanz referenzieren (z. B. ein Nachrichtenobjekt in Outlook), ruft ReleaseComObject in Ihrer AppDomain nicht auf, dass RCWs in anderen AppDomains den Verweis auf diese Instanz verlieren.

+0

Wenn wir diese Annahme machen, dann geht die Frage nach Definition der „Instanz“ - also sagen wir mal jede Nachricht ist ein Objekt - bedeutet es, dass jeder Zugabe erstellt/verwendet verschiedene COM (Instanz) für den Zugriff auf die Nachricht, oder es gibt ein einzelnes COM-Objekt (Instanz) und alle greifen darauf zu? –

+0

Ein von Outlook verfügbares Nachrichtenobjekt ist wahrscheinlich freigegeben - eine einzelne Instanz. Jede AppDomain hat jedoch einen eigenen Zeiger (RCW) für diese Instanz und behält ihre eigene interne Referenzzahl bei (wenn Mason korrekt ist und ich glaube, dass er das ist). –

+0

Mason kann für die Zeit des Artikels korrekt sein, da in 1.1-Dokumenten nicht "process", sondern in 2.0 und späterem Frameworks "pro Prozess" angegeben wird, nicht pro AppDomain. –

3

Der Artikel Blog Mason Bendixen, dass Ilya zitiert ist richtig: die RCW auf die AppDomain scoped ist, nicht an den Prozess. Ich kann nur vermuten, dass der Artikel Runtime Callable Wrapper (MSDN 2.0) "beiläufig" gesprochen hat. Dieser Artikel ist nicht notwendigerweise im allgemeinen Sinn falsch, da es am typischsten ist, nur mit einer einzigen Anwendungsdomäne zu arbeiten, aber dieser Satz ist technisch nicht genau.

In Bezug auf Ihre Frage:.

„Ich möchte wissen, was passiert, wenn ich Marshal.ReleaseComObject (x) in einer Schleife verwenden , bis es Zahl ist erreicht 0 (als empfohlen) Will es release Referenzen von anderen Addins (läuft in anderen Anwendungsdomäne im selben Outlook-Prozess)? "

Die Antwort darauf hängt davon ab, wie Sie Ihr Add-In einrichten. Wenn Sie keine Vorkehrungen treffen, lautet die Antwort im Allgemeinen ja, dass sich dies auf die Referenzen in anderen Add-Ins auswirkt, die in derselben AppDomain ausgeführt werden. Aber da Sie angeben, dass Sie von einer separaten AppDomain ausgeführt werden, würde dies nicht der Fall sein.

Es gibt eine COM Shim Wizard Version 2.3.1, die Sie verwenden können, um Ihr Add-In zu isolieren. Die Dokumentation zum COM Shim Wizard finden Sie hier: Isolating Microsoft Office Extensions with the COM Shim Wizard Version 2.3.1.

Der COM Shim-Assistent verwendet Reflektion zum Erstellen eines benutzerdefinierten COM-Front-Loaders, der Ihre Add-In-Assembly in eine separate AppDomain lädt. Dies schafft Sicherheit in zweifacher Hinsicht:

(1) Durch Verwendung eines separaten, angepassten COM-Einstiegspunkts wird Ihr Add-In von Microsoft Office von allen anderen Add-Ins korrekt erkannt. Ansonsten teilen sich alle Add-Ins standardmäßig den gleichen Standard-Ladevorgang mscoree.dll. Das Problem bei der Freigabe desselben Ladeprogramms besteht darin, dass mscoree.dll von Microsoft Office als Quelle des Problems erkannt wird, wenn ein Add-In einen Absturz aufweist, und es beim nächsten Mal nicht automatisch geladen wird. Sie können es manuell erneut aktivieren, aber Ihr Add-In würde beim nächsten Mal aufgrund eines Problems im Add-In von jemand anderem nicht automatisch geladen werden!

(2) Durch das Laden Ihrer Assembly in einer separaten Anwendungsdomäne werden die aufrufbaren Laufzeit-Wrapper (RCWs) von den anderen Add-Ins isoliert, die in denselben Prozess geladen werden. Wenn Sie in diesem Fall Marshal.ReleaseComObject (Objekt) oder Marshal.FinalReleaseComObject (Objekt) aufrufen, würden Sie die Add-Ins anderer Benutzer nicht beeinflussen. Noch wichtiger: Wenn eines dieser anderen Add-Ins solche Aufrufe tätigt, ist Ihr Add-In vor einer Beschädigung geschützt. :-)

Der Nachteil bei der Verwendung des COM Shim Wizard besteht darin, dass durch die Verwendung einer separaten AppDomain zusätzlicher Marshalling-Aufwand entsteht. Ich glaube nicht, dass dies für ein Microsoft Outlook-Add-In auffallen sollte. Es kann jedoch ein Faktor für einige intensive Routinen sein, die viele Aufrufe an das Objektmodell haben, wie dies manchmal für ein Microsoft Excel-Add-In der Fall sein kann.

Sie haben angegeben, dass Sie Ihr Add-In bereits über eine separate AppDomain ausführen. Wenn dies zutrifft, sind Sie bereits von Marshal.ReleaseComObject (Objekt) und Marshal.FinalReleaseComObject (Objekt) -Aufrufen in Bezug auf andere AppDomains isoliert. (Ich bin neugierig, wie Sie dies übrigens tun ... Erstellen Sie explizit Ihre eigene AppDomain? Die Standard-Add-In-Vorlage in Visual Studio nicht in separaten AppDomain ausführen und lädt mit der mscoree.dll .)

Wenn Sie Ihre eigene AppDomain erstellen, ist Ihr Code zwar isoliert, seine Identität ist jedoch möglicherweise nicht von anderen Add-Ins getrennt, da Ihr Add-In den standardmäßigen mscoree.dll-Loader weiterhin verwendet Sie haben einige andere Mittel verwendet, um dies zu beheben.

Ich hoffe, das hilft ...

+0

Danke für die Antwort. Ich benutze die Shim-Lösung. Aber ich bin immer noch verwirrt wegen des Begriffs "Prozess" in RCW Dokumentation (ver. 2.0 und höher). Und Prozess ist keine App-Domäne. –

+0

Können Sie ein Dokument bereitstellen, das Ihre (2) -Anweisung bestätigt - "Durch das Laden Ihrer Assembly in einer separaten Anwendungsdomäne werden die Runtime Callable Wrappers (RCWs) von den anderen Add-Ins isoliert, die in denselben Prozess geladen werden." –

+0

Dafür würde ich den Link lesen, den ich oben auf den Artikel "Isolieren von Microsoft Office-Erweiterungen mit dem COM Shim Wizard Version 2.3.1" gefunden habe, finden Sie unter http://msdn.microsoft.com/en-us/library/ bb508939.aspx, vor allem der Abschnitt mit dem Titel "Wie die COM Shim funktioniert". –