传递对象以接收从在流程中创建的子AppDomain的回调到Default AppDomain

Abb*_*bby 5 c# ipc appdomain

座谈会:

  1. 我正在从进程中创建子应用程序域以加载程序集。
  2. 我可以拨打此AppDomain的电话。
  3. 我想将一个对象从默认进程AppDomain传递到此新创建的AppDomain,以接收从在新AppDomain中加载的程序集到我的默认AppDomain的回调。

我发现的一种方法是使用AppDomain.DoCallback方法,但是不确定如何在子AppDomain中获取主机AppDomain?

任何机构都有实现它的想法吗?

Mic*_*ski 5

一般的想法是将派生自MarshalByRefObject类的类的实例传递给新创建的域。它将保证该对象将通过引用而不是值进行编组。这意味着代理将被传递到新域,而不是原始对象(该代理将由.NET框架为您生成)。

稍后,当您在此代理上调用方法时,此调用将被传递回原始域(创建对象的域)。换句话说,将在原始域中执行一种方法。

这是显示此想法的代码:

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

运行此代码时,将得到以下结果:

[Init] Hello from otherDomain domain
[Callback] Hello from Sandbox.vshost.exe domain
Run Code Online (Sandbox Code Playgroud)

它显示了Init方法是在新域中执行的,但在原始域中执行了回调。现在,用2行注释: MarshalByRefObject并再次运行该程序。这次Listener将通过值传递到新域,结果将是:

[Init] Hello from Sandbox.vshost.exe domain
[Callback] Hello from Sandbox.vshost.exe domain
Run Code Online (Sandbox Code Playgroud)