传递一个对象以从进程中创建的子 AppDomain 接收回调到默认 AppDomain [英] Passing an object to receive callback from a child AppDomain created within a process to Default AppDomain
问题描述
地点:
- 我正在从我的进程中创建一个子应用程序域来加载程序集.
- 我可以调用此 AppDomain.
- 我想将一个对象从我的默认进程 AppDomain 传递到这个新创建的 AppDomain,以接收从新 AppDomain 中加载的程序集到我的默认 AppDomain 的回调.
我发现的一种方法是使用 AppDomain.DoCallback 方法,但不确定如何在我的子 AppDomain 中获取我的主机 AppDomain?
One way I found is to use the AppDomain.DoCallback method, however not sure how to get my host AppDomain in my child AppDomain?
任何机构有实现它的想法吗?
Any body have any idea to achieve it?
推荐答案
总体思路是向新创建的域传递一个从 MarshalByRefObject
类派生的类的实例.它将保证此对象将按引用而不是按值编组.这意味着一个代理将传递到新域而不是原始对象(此代理将由 .NET 框架为您生成).
The general idea is to pass to the newly created domain an instance of a class that is derived from MarshalByRefObject
class. It will guarantee that this object will be marshaled by reference and not by value. It means that a proxy will be passed to the new domain and not the original object (this proxy will be generated for you by .NET framework).
稍后当您在此代理上调用方法时,此调用将传递回原始域(创建对象的域).换句话说,一个方法将在原始域中执行.
Later on when you call a method on this proxy, this call will be passed back to the original domain (a domain where the object was created). In other words a method will be executed in the original domain.
这是一个展示这个想法的代码:
Here is a code that shows this idea:
public class Program
{
private static void Main(string[] args)
{
var listener = new Listener();
var otherDomain = AppDomain.CreateDomain("otherDomain");
var instance = (Loader)otherDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Loader).FullName);
instance.Init(listener);
}
}
[Serializable]
public class Loader
: MarshalByRefObject
{
public void Init(Listener listener)
{
Console.WriteLine($"[{nameof(Init)}] Hello from {AppDomain.CurrentDomain.FriendlyName} domain");
listener.Callback();
}
}
[Serializable]
public class Listener
: MarshalByRefObject
{
public void Callback()
{
Console.WriteLine($"[{nameof(Callback)}] Hello from {AppDomain.CurrentDomain.FriendlyName} domain");
}
}
当您运行此代码时,您将得到以下结果:
When you run this code you will get the following result:
[Init] Hello from otherDomain domain
[Callback] Hello from Sandbox.vshost.exe domain
显示Init方法在新域中执行,但在原域中回调.现在用 : MarshalByRefObject
注释 2 行并再次运行该程序.这次Listener
会按值传给新域,结果为:
It shows that Init method was executed in a new domain but a callback in the original one. Now comment 2 lines with : MarshalByRefObject
and run the program one more time. This time Listener
will be passed to the new domain by value and the result will be:
[Init] Hello from Sandbox.vshost.exe domain
[Callback] Hello from Sandbox.vshost.exe domain
这篇关于传递一个对象以从进程中创建的子 AppDomain 接收回调到默认 AppDomain的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!