6

アンマネージ COM オブジェクトを参照するときのランタイム呼び出し可能ラッパー (RCW) のスコープは何ですか? ドキュメントによると:

ランタイムは、そのオブジェクトに存在する参照の数に関係なく、COM オブジェクトごとに正確に 1 つの RCW を作成します。

「推測」しなければならない場合、この説明は「プロセスごとに1つ」を意味するはずですが、それは本当ですか? 追加のドキュメントは大歓迎です。

私のアプリケーションは独自のアプリケーション ドメイン (Outlook アドイン) で実行されます。カウントが 0 になるまでループで Marshal.ReleaseComObject(x) を使用するとどうなるかを知りたいです (推奨)。他のアドイン (同じ Outlook プロセス内の他のアプリケーション ドメインで実行されているもの) から参照を解放しますか?

編集:パーフェクト - 今、混乱はさらに大きくなっています。2 つの回答 (Lette と Ilya から) に基づいて、2 つの異なる回答があります。MSDNの公式ドキュメントにはプロセスごと (ver. 2.0 以降の場合) と書かれていますが、ver. 2.0 以降ではこの文がありません。ドキュメントの1.1

同時に、Mason Bendixen の記事では、それは appdomain ごとであると述べています。

彼の記事は古い (2007 年 4 月) ため、明確化を求めるメールを彼に送信しましたが、他の誰かが何かを追加する必要がある場合は、追加してください。

ありがとう

4

3 に答える 3

3

Ilyaが引用しているMasonBendixenのブログ記事は正しいです。RCWはプロセスではなくAppDomainにスコープされています。Runtime Callable Wrapper(MSDN 2.0)の記事が「カジュアルに」話していたと推測できます。単一のAppDomainのみを使用して実行するのが最も一般的であるため、その記事は一般的な意味で必ずしも正しくありませんが、その文は技術的に正確ではありません。

あなたの特定の質問に関して:

「カウントが0に達するまでループでMarshal.ReleaseComObject(x)を使用するとどうなるか知りたいです(推奨)。他のアドイン(同じOutlookプロセスの他のアプリケーションドメインで実行されている)からの参照を解放しますか? ?」

これに対する答えは、アドインの設定方法によって異なります。一般に、予防策を講じない場合、答えは「はい」です。同じAppDomain内で動作する他のアドインの参照に影響を与えます。ただし、別のAppDomainから実行していると述べているので、そうではありません。

アドインを分離するために使用できるCOMShimWizardバージョン2.3.1があります。COM Shim Wizardのドキュメントは、次の場所にあります。COMShimWizardバージョン2.3.1を使用したMicrosoftOffice拡張機能の分離

COM Shim Wizardは、リフレクションを使用して、別のAppDomain内にアドインアセンブリをロードするカスタマイズされたCOMフロントエンドローダーを構築します。これにより、2つの点で安全性が生まれます。

(1)個別のカスタマイズされたCOMエントリポイントを使用することにより、アドインはMicrosoftOfficeによって他のすべてのアドインとは別に正しく識別されます。それ以外の場合、デフォルトでは、すべてのアドインが同じデフォルトのmscoree.dllローダーを共有します。同じローダーを共有する場合の問題は、アドインにクラッシュが発生した場合、mscoree.dllがMicrosoft Officeによって問題の原因として識別され、次回は自動的に読み込まれないことです。手動で再度オンにすることはできますが、他の誰かのアドインに問題があるため、次回はアドインが自動的に読み込まれません。

(2)アセンブリを別のAppDomain内にロードすることにより、ランタイム呼び出し可能ラッパー(RCW)は、同じプロセスにロードされる他のアドインから分離されます。この場合、Marshal.ReleaseComObject(object)またはMarshal.FinalReleaseComObject(object)を呼び出すと、他の人のアドインに影響を与えることはありません。さらに重要なことに、これらの他のアドインのいずれかがそのような呼び出しを行う場合、アドインは破損から保護されます。:-)

COM Shim Wizardを使用することの欠点は、別のAppDomainから操作することにより、余分なマーシャリングのオーバーヘッドが発生することです。これは、MicrosoftOutlookアドインでは目立たないと思います。ただし、Microsoft Excelアドインの場合など、オブジェクトモデルへの呼び出しが多い一部の集中的なルーチンでは、これが要因になる可能性があります。

別のAppDomainからアドインをすでに実行しているとのことです。これが当てはまる場合は、他のAppDomainに関してMarshal.ReleaseComObject(object)およびMarshal.FinalReleaseComObject(object)呼び出しからすでに分離されています。(ちなみに、これをどのように行っているのか興味があります...独自のAppDomainを明示的に作成していますか?Visual Studioの既定のアドインテンプレートは、個別のAppDomainで実行され、mscoree.dllを使用して読み込まれます。)

独自のAppDomainを作成している場合、コードは分離されていますが、他の手段を利用しない限り、アドインはデフォルトのmscoree.dllローダーを共有しているため、そのIDは他のアドインから分離されていない可能性があります。これに対処します。

これがお役に立てば幸いです...

于 2008-10-04T13:48:33.473 に答える
3

マネージドでは、正規の IUnknown を RCW にマッピングするアプリごとのドメイン キャッシュがあります。IUnknown が (マーシャル呼び出し、アクティブ化、メソッド呼び出しからの戻りパラメーターなどによって) システムに入ると、キャッシュをチェックして、COM オブジェクトの RCW が既に存在するかどうかを確認します。マッピングが存在する場合、既存の RCW への参照が返されます。それ以外の場合は、新しい RCW が作成され、キャッシュ マッピングが追加されます。

メイソンのブログより

于 2008-10-02T15:59:28.097 に答える
1

同じドキュメントによると:

ランタイムは、各オブジェクトのプロセスごとに 1つの RCW を維持します。

object = instanceであると安全に想定できると思います。そのため、addins/AppDomains が同じインスタンスへの参照を保持していない場合、 への呼び出しは、別のReleaseComObject場所で作成されたインスタンスへの参照を解放しません。

編集: 他の場所で述べられているように、ドキュメントの文言は間違っている可能性があります。その場合、アドインは別の AppDomain で実行されているので、幸運です。異なるアドインが同じインスタンス (Outlook のメッセージ オブジェクトなど) を参照している場合でも、AppDomain でReleaseComObject呼び出されても、他の AppDomain の RCW がそのインスタンスへの参照を失うことはありません。

于 2008-10-02T15:56:02.283 に答える