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

时间:2022-02-16 22:19:56

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?

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

5 个解决方案

#1


26  

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.

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

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

编辑:请参阅此处以获取更多详细信息,包括实施示例的链接。

#2


12  

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.

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

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.

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

-Oisin

-Oisin

#3


9  

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

我刚刚发现您也可以使用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);
}

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

您还可以使用AppDomain.FirstChanceException事件在子应用程序和主机应用程序域之间创建异常驱动的通信:)

#4


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.

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

#5


1  

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.

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

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.

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

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.

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

#1


26  

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.

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

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

编辑:请参阅此处以获取更多详细信息,包括实施示例的链接。

#2


12  

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.

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

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.

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

-Oisin

-Oisin

#3


9  

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

我刚刚发现您也可以使用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);
}

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

您还可以使用AppDomain.FirstChanceException事件在子应用程序和主机应用程序域之间创建异常驱动的通信:)

#4


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.

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

#5


1  

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.

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

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.

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

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.

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