How best to communicate between AppDomains?
Asked Answered
I

6

39

I have an application that needs to send a moderately high volume of messages between a number of AppDomains. I know that I could implement this using remoting, but I have also noticed that there are cross-domain delegates. Has anyone looked at this kind of problem?

Infirmity answered 24/11, 2008 at 14:26 Comment(3)
WCF using named pipes looks like the favourite to me - I can then at least avoid the necessity of going onto the network. Thanks everyone!Infirmity
Care to elaborate about this technique? for example, what's the performance cost of using named pipes and the ease of use compared with AppDomains and MBRO (MarshalByRefObject).Dispensable
I don't have any figures to hand, but using a binary serializer and named pipes has allowed me to communicate pretty much seamlessly between domains. I came up with a simple message bus and have been able to simply ignore the problem ever since.Infirmity
N
27

I have had good success using WCF with a named pipes binding. Using named pipes creates no network traffic and uses binary encoding, so it should be pretty fast without sacrificing the ability to distribute in future scaling scenarios.

EDIT: Refer here for more detailed information including a link to an implementation example.

Narcis answered 24/11, 2008 at 14:52 Comment(1)
IPC allows processes to communicate each other and synchronize their actions but not for the app-domain communication. Correct me if i am wrong.Pilgarlic
B
13

A cross-domain delegate only allows a void method with zero parameters, and it's probably not what you think it is. It's only barely useful as a simple callback for notification purposes from one appdomain to another, e.g. a method like InitComplete() or something.

Remoting is the ONLY choice, whether you call it WCF or whatever else, passing serializable types, or using MBRO types (MarshalByRefObjects). It's not as hard as you think.

-Oisin

Bryant answered 24/11, 2008 at 15:27 Comment(4)
Remoting sound .NET 1.1 to me. Is there any newer alternatives for doing cross-appdomain communication?Dispensable
Remoting never went away. It's still used everywhere. The modernation of WCF came for cross process (IPC) calls. But for appdomains, it's always been remoting. You could use WCF with named pipes, but meh. Remoting is less hassle IMO.Bryant
@x0n, [Remoting is] a legacy technology that is retained for backward compatibility with existing applications and is not recommended for new development. Distributed applications should now be developed using the Windows Communication Foundation (WCF). msdn.microsoft.com/library/72x4h507.aspxSpectacle
@Spectacle Yep, I agree - I probably should have made the distinction clearer, but it was four years ago :DBryant
A
10

I just discovered that you may also use the AppDomain.SetData but this is only one way From Host Domain to Child Domain.

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);
}

You can also create exception driven communication between child and host appdomain by using AppDomain.FirstChanceException event :)

Aquarist answered 17/6, 2012 at 12:19 Comment(1)
I'm sorry for reheating such an old question, but it is not only one way from Parent Domain to Child Domain. You can use SetData like this: childDomain.SetData("domain", AppDomain.CurrentDomain); and then perform GetData("domain") in Child Domain to perform yet another Set/GetData and DoCallBack.Kannada
T
5

CallContext allows passing data between AppDomains:

   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");

The code uses System.Runtime.Remoting.Messaging. I personally didn't measure the performance of this solution.

Tabb answered 1/8, 2018 at 20:8 Comment(1)
This works between ANY two domains, not just parent child. +1Nape
R
3

This is just a quick thought, but I heard that even for cross-domain communication WCF would be the recommended approach, starting from .NET 3.0 of course. Actually this makes sense, as remoting is just another technology wrapped by WCF.

Retha answered 24/11, 2008 at 14:30 Comment(0)
A
2

I want to expand on xOn's answer. He recommends using either WCF or MarshalByRefObject, but given that the question asks about communication between AppDomains, and not about communication between processes, I think the MBRO approach is significantly simpler to implement, and is therefore the right answer.

When I was researching this issue myself, I struggled at first to understand how the child AppDomain could communicate with the parent, until I realized that you could pass a handle to a MBRO object into the child, and the child could then unwrap that handle to communicate back to the parent (or any other AppDomain). I posted a solution to my own question here.

I subsequently learned that you can define an interface, implement that interface on a complex class, and then pass a handle to only the interface. This can greatly reduce the number of assemblies that might be required to load the child AppDomain.

Amari answered 9/6, 2016 at 12:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.