9

核となる問題は次のとおりです。別の AppDomain でCOM 相互運用機能を使用する .NET アプリケーションがあります。COM スタッフは、COM スタッフが呼び出されている AppDomain ではなく、アセンブリをデフォルト ドメインにロードしているようです。

私が知りたいのは、これは予想される動作ですか、それとも、これらの COM 関連のアセンブリが間違った AppDomain に読み込まれるようにするために何か間違ったことをしているのですか? 以下の状況の詳細な説明を参照してください...

アプリケーションは 3 つのアセンブリで構成されています。 - アプリケーションのエントリ ポイントであるメイン EXE。- インターフェイス IController (IPlugin スタイル) のみを含む common.dll - IController および MarshalByRefObject を実装する Controller クラスを含む controller.dll。このクラスはすべての作業を行い、COM 相互運用機能を使用して別のアプリケーションと対話します。

メイン EXE の関連部分は次のようになります。

AppDomain controller_domain = AppDomain.CreateDomain("Controller Domain");
IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap("controller.dll", "MyNamespace.Controller");
result = c.Run();
AppDomain.Unload(controller_domain);

common.dll には、次の 2 つだけが含まれています。

public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun}
public interface IController
{
    ControllerRunResult Run();
}

そして、controller.dll には次のクラスが含まれています (COM 相互運用機能も呼び出します)。

public class Controller: IController, MarshalByRefObject

アプリケーションを最初に実行すると、Assembly.GetAssemblies() は予想どおりに表示され、common.dll は両方の AppDomains に読み込まれ、controller.dll はコントローラー ドメインにのみ読み込まれます。ただし、c.Run() を呼び出した後、COM 相互運用機能に関連するアセンブリがデフォルトの AppDomain に読み込まれ、COM 相互運用が行われている AppDomain には読み込まれていないことがわかります。

なぜこれが起こっているのでしょうか?

興味がある場合は、ここに少し背景があります。

もともと、これは 1 AppDomain アプリケーションでした。それがインターフェースするCOMのものは、長期間使用すると安定しないサーバーAPIです。COM から COMException (その原因に関する有用な診断情報がない) が発生した場合、COM 接続が再び機能する前に、アプリケーション全体を再起動する必要があります。COM アプリケーション サーバーに再接続するだけで、再びすぐに COM 例外が発生します。これに対処するために、COM 相互運用機能を別の AppDomain に移動しようとしました。これにより、謎の COMExceptions が発生したときに、それが発生した AppDomain をアンロードし、新しいものを作成して、アプリケーションを手動で再起動することなく、最初からやり直すことができます。 . とにかくそれが理論でした...

4

3 に答える 3

17

残念ながら、COM コンポーネントは AppDomain のコンテキスト内ではなく、プロセス スペース内に読み込まれます。そのため、ネイティブ DLL を手動で分解 (リリースおよびアンロード) する必要があります (COM と P/Invoke の両方に適用されます)。appdomain を単に破棄するだけでは何の役にも立ちませんが、COM の状態をリセットするためにプロセス全体を再生成する必要はありません (単純に COM オブジェクトを再作成するだけでも正常に動作するはずです。これはおそらくコンポーネント プロバイダー コード内のバグのように思えます)。彼らはそれに対処できますか?)

参考文献

(TechNet) プロセス アドレス空間

(MSDN) アプリケーション ドメイン

(MSDN) 境界: プロセスと AppDomains

于 2009-11-06T04:43:45.260 に答える
3

これがショーン・ウィルソンの答えが正しいという証拠です

Com アプリ ドメイン

于 2013-01-11T17:26:37.437 に答える
0

コントローラーを MBR にしないでください。2 番目のドメインに Controller をロードして起動する小さなプロキシを作成します。そうすれば、Controller dll は最初のドメインにロードされません。

于 2008-10-28T15:52:43.070 に答える