如何在AppDomains之间进行最佳通信?

时间:2008-11-24 14:26:07

标签: c# .net remoting appdomain

我的应用程序需要在多个AppDomain之间发送大量的消息。我知道我可以使用远程处理实现这一点,但我也注意到有跨域委托。有谁看过这种问题?

6 个答案:

答案 0 :(得分:26)

我使用带有命名管道绑定的WCF取得了很好的成功。使用命名管道不会创建网络流量并使用二进制编码,因此它应该非常快,而不会牺牲在未来扩展方案中分发的能力。

编辑: 有关更多详细信息,请参阅here,包括指向实施示例的链接。

答案 1 :(得分:12)

跨域委托只允许使用零参数的void方法,并且它可能不是您认为的那样。它仅作为从一个应用程序域到另一个域的通知目的的简单回调几乎没有用,例如像InitComplete()或类似的方法。

Remoting是唯一的选择,无论你是将它称为WCF还是其他任何东西,传递可序列化类型,或使用MBRO类型(MarshalByRefObjects)。它并不像你想象的那么难。

-Oisin

答案 2 :(得分:10)

我刚刚发现你也可以使用AppDomain.SetData,但这只是一种方法 从主机域到子域。

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事件在子域和主机应用程序域之间创建异常驱动的通信:)

答案 3 :(得分:3)

这只是一个简单的想法,但我听说即使是跨域通信 WCF 也是推荐的方法,当然从.NET 3.0开始。实际上这是有道理的,因为远程处理只是WCF包含的另一项技术。

答案 4 :(得分:2)

我想扩展xOn的答案。他建议使用WCF或MarshalByRefObject,但考虑到问题是关于AppDomains之间的通信,而不是关于进程之间的通信,我认为MBRO方法实现起来非常简单,因此是正确答案。

当我自己研究这个问题时,我一开始就努力了解子AppDomain如何与父进行通信,直到我意识到你可以将一个句柄传递给一个MBRO对象进入孩子,然后孩子可以解开处理回传给父(或任何其他AppDomain)的句柄。我发布了自己的问题here的解决方案。

我后来了解到,您可以定义一个接口,在复杂的类上实现该接口,然后只将句柄传递给接口。这可以大大减少加载子AppDomain可能需要的程序集数量。

答案 5 :(得分:2)

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。我个人没有衡量此解决方案的性能。