web-dev-qa-db-ja.com

AppDomain間で通信するのに最適な方法は?

多数のAppDomain間で適度に大量のメッセージを送信する必要があるアプリケーションがあります。リモーティングを使用してこれを実装できることは知っていますが、クロスドメインデリゲートがあることにも気づきました。誰かがこの種の問題を見たことがありますか?

39
open-collar

名前付きパイプをバインドするWCFを使用して成功しました。名前付きパイプを使用すると、ネットワークトラフィックが作成されず、バイナリエンコーディングが使用されるため、将来のスケーリングシナリオで分散する機能を犠牲にすることなく、かなり高速になります。

編集:実装例へのリンクを含む詳細情報については、 ここ を参照してください。

27
Michael Meadows

クロスドメインデリゲートは、パラメータがゼロのvoidメソッドのみを許可し、おそらくそれはあなたが思っているものではありません。これは、あるアプリドメインから別のアプリドメインへの通知を目的とした単純なコールバックとしてはほとんど役に立ちません。 InitComplete()などのメソッド。

リモーティングは、WCFと呼ぶか、シリアル化可能な型を渡すか、MBRO型(MarshalByRefObjects)を使用するかにかかわらず、唯一の選択肢です。思ったほど難しくはありません。

-オシーン

13
x0n

AppDomain.SetDataも使用できることを発見しましたが、これはホストドメインから子ドメインへの1つの方法にすぎません。

static void RunInChildDomain()
{
     AppDomain childDomain = AppDomain.CreateDomain("friendlyName");
     string parameterValue = "notmii";
     childDomain.SetData("parameter", parameterValue);
     childDomain.DoCallBack(PrintName);
}

static void PrintName()
{
     string Name = Convert.ToString(AppDomain.CurrentDomain.GetData("parameter"));
     Console.WriteLine(Name);
}

AppDomain.FirstChanceExceptionイベントを使用して、子とホストappdomain間の例外駆動型通信を作成することもできます:)

10
notmii

これは簡単な考えですが、クロスドメイン通信の場合でも[〜#〜] wcf [〜#〜]が、もちろん.NET3.0以降の推奨アプローチになると聞きました。リモーティングはWCFによってラップされた別のテクノロジであるため、実際にはこれは理にかなっています。

3
lvaneenoo

CallContextを使用すると、AppDomain間でデータを渡すことができます。

   CallContext.LogicalSetData("Key", "My value");
   Console.WriteLine("{0} from {1}", CallContext.LogicalGetData("Key"),               
   AppDomain.CurrentDomain.FriendlyName);

   var appDomain = AppDomain.CreateDomain("Worker");
   appDomain.DoCallBack(() => Console.WriteLine("{0} from {1}", 
       CallContext.LogicalGetData("Key"), 
       AppDomain.CurrentDomain.FriendlyName));
   AppDomain.Unload(appDomain);

   CallContext.FreeNamedDataSlot("Key");

コードはSystem.Runtime.Remoting.Messagingを使用します。私は個人的にこのソリューションのパフォーマンスを測定しませんでした。

3
Vadim S.

XOnの答えを拡張したいと思います。彼はWCFまたはMarshalByRefObjectのいずれかを使用することを推奨していますが、質問がプロセス間の通信ではなくAppDomain間の通信について尋ねていることを考えると、MBROアプローチは実装が非常に簡単であり、したがって正しい答えだと思います。

この問題を自分で調べていたとき、最初は子AppDomainが親と通信する方法を理解するのに苦労しましたが、MBROオブジェクトへのハンドルを子に渡して、子がそのハンドルを親(または他のAppDomain)と通信します。私は自分の質問に対する解決策を投稿しました ここ

その後、インターフェイスを定義し、そのインターフェイスを複雑なクラスに実装してから、インターフェイスのみにハンドルを渡すことができることを学びました。これにより、子AppDomainのロードに必要となる可能性のあるアセンブリの数を大幅に減らすことができます。

2
Bert Cushman