AppDomains之间的通信

Posted

技术标签:

【中文标题】AppDomains之间的通信【英文标题】:Communication between AppDomains 【发布时间】:2012-01-23 13:26:49 【问题描述】:

我们正在构建一个将“插件”DLL 加载到辅助 AppDomain 的应用程序(WinForms、.NET 3.5)。辅助 AppDomain 需要偶尔与第一个 AppDomain 通信(更具体地说,调用或从主 AppDomain 中创建的对象获取数据)。

我已经阅读了大部分关于 AppDomain 和它们之间的通信的材料。

到目前为止,我见过的唯一简单的解决方案是从 MarshalByRefObject 继承并传递 TransparentProxy进入第二个 AppDomain,调用 Proxy 上的方法。

此方法有其缺点(例如,在框架类型或已经从另一个类、静态字段/类等继承的类型的情况下,并不总是可以从 MBRO 继承)。

由于当前的通信点相当稳定(只有 2-3 个需要通信的场景),我考虑创建一个具有以下属性的简单 Mediator 类:

    将在第一个(主)AppDomain 中创建。 只能作为在主 AppDomain 中创建的“真实”对象的“消息传递者”。 将从 MBRO 继承,并且对它的代理引用将被发送到第二个 AppDomain。

将调用此代理对象上的方法,然后调用第一个 AppDomain 中“真实”对象上的方法。

我的问题--

    这看起来是合乎逻辑的设计吗? 更重要的是,WCF 或任何其他通信框架中是否已经存在调解器/消息传递器类?这似乎是一个通用概念,我想知道是否有类似的东西。

【问题讨论】:

通过阅读Plugin这一点,我总是首先问:“你听说过MEF吗?” 是的,我听说过。 AFAIK 它内置在 .NET 中,不确定是否支持早期版本......另外,我不确定它如何适合这个特定场景。 我意识到距离最初的帖子已经过去了 18 个月。我想知道你是怎么弄出来的。我们面临着类似的限制,MEF 本身无法解决,而 MAF 似乎已经走上了渡渡鸟的道路。 我们所做的是设置一个 WCF 服务,该服务将充当这个中介 PER 子系统,需要来自第二个应用域的通信(我们只有其中的两个)。此外,我们确保此中介器支持的接口非常简单(接受/返回原始类型的方法,如字符串等)。 “插件”应用程序域将为该对象创建一个 WCF 代理(使用命名管道)。这样,我们就可以在两个 appdomain 之间进行通信了。 【参考方案1】:

除非您出于某种原因特别想避免使用 WCF,否则我建议您看看它。具体来说,您可以使用 NetNamedPipeBinding,它使用命名管道在同一台机器上提供通信。您可以在此处找到更多信息: http://msdn.microsoft.com/en-us/library/system.servicemodel.netnamedpipebinding.aspx

同样,这里有一个相当简洁的blog entry demonstrating it's use(从 WMP 插件到第三方应用程序)。

根据您对应用程序的描述,您可以在第一个 AppDomain 中建立 WCF 服务,然后从第二个 AppDomain 调用该服务。

【讨论】:

谢谢,我会检查一下。一个问题——为什么人们提倡使用不同传输介质的命名管道?它有什么优势? 在 WCF 的上下文中,通过命名管道进行的通信是最适合在单个机器上进行通信的机制。事实上,您不能通过端点与另一台机器的 NetNamedPipeBinding 进行通信。开箱即用的替代绑定通常在协议方面更重(因此 NetNamedPipedBinding 可能会更高效),一旦您开始使用它们,您需要开始更加关注安全性(例如,锁定如果您使用的是 NetTcpBinding,请关闭端口)。 coden-p-managed-wmp-plugin-wcf-ipc 的链接坏了,你知道另一个吗? @FrankSchwieterman 这是您要查找的链接吗? vikingco.de/codesnippet-managed-windows-media-plugins.html @FrankSchwieterman 这是正确的链接:vikingco.de/codesnippet-managed-wmp-plugin-wcf-ipc.html

以上是关于AppDomains之间的通信的主要内容,如果未能解决你的问题,请参考以下文章

插件 AppDomains 解决方法

AppDomains、卸载和 ThreadAbortException

跨 AppDomains 的 NLog 配置

试图避免 AppDomains

如何跨 AppDomains 订阅事件(object.Event += handler;)

几个appdomains调用相同的非托管DLL