传递一个对象以从进程中创建的子 AppDomain 接收回调到默认 AppDomain [英] Passing an object to receive callback from a child AppDomain created within a process to Default AppDomain

查看:21
本文介绍了传递一个对象以从进程中创建的子 AppDomain 接收回调到默认 AppDomain的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

地点:

  1. 我正在从我的进程中创建一个子应用程序域来加载程序集.
  2. 我可以调用此 AppDomain.
  3. 我想将一个对象从我的默认进程 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆