【问题标题】:Run action in AppDomain in .NET 5在 .NET 5 中的 AppDomain 中运行操作
【发布时间】:2021-07-19 17:44:56
【问题描述】:

我正在将应用程序从 .NET Framework 迁移到 .NET 5.0。

在我之前的实现中,我从外部源动态读取程序集,然后将它们加载到不同的 AppDomain 中,然后通过 CrossAppDomainDelegate 运行 Action。

将为每个程序集运行的代码示例:

var setup = new AppDomainSetup
{
    ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
};

var domain = AppDomain.CreateDomain($"MyDomain", null, setup);
var del = new CrossAppDomainDelegate(action); // The action I'm running

domain.DoCallBack(del);

在 .NET 5.0 中,我仍然可以创建域(即使我不能像以前那样使用设置)但我似乎无法找到通过委托运行操作的方法,因为 CrossAppDomainDelegate 是不再支持。

关于如何实现这一目标的任何想法?甚至可能吗? 如果没有,还有什么方法可以实现这个功能?

【问题讨论】:

  • @valerysntx:鉴于该线程是十年前的并且属于 .NET 框架,我怀疑这将解决 OP 的问题,该问题特定于新的 .NET 5。
  • @JeremyCaney,我认为这是相关的,因为可以使用CreateInstanceAndUnwrap

标签: c# .net-core .net-5


【解决方案1】:

考虑将 AppDomain 类的 CreateInstanceAndUnwrap 方法与跨应用委托的 MarshalByRefObject 代理实现一起使用,例如:


public interface IRuntime
{
    object Run<T>(Expression<Func<T>> del);
}


public class Runtime : MarshalByRefObject, IRuntime
{
    public object Run<T>(Expression<Func<T>> del)
    {
        return del.Compile().Invoke();
    }
}


void Main()
{
    AppDomain childDomain = null;
    try
    {


        // Create the child AppDomain 
        childDomain = AppDomain.CurrentDomain;
        // AppDomain.CreateDomain("Your Child AppDomain"); //supported? NET5.0

        // Create an instance of the runtime in the second AppDomain. 
        // A proxy to the object is returned.
        IRuntime runtime = (IRuntime) childDomain.CreateInstanceAndUnwrap(
                                       typeof(Runtime).Assembly.FullName,                                                                    
                                       typeof(Runtime).FullName);



        // start the runtime.  call will marshal into the child runtime appdomain
        runtime.Run<string>(() => "hello!").Dump();
    }
    finally
    {
        // runtime has exited, finish off by unloading the runtime appdomain
        if (childDomain != null && childDomain != AppDomain.CurrentDomain) AppDomain.Unload(childDomain);
    }

}

【讨论】:

  • 谢谢@valerysntx,工作就像一个魅力!我改变的一件事是委托运行一个 Action 而不是 Func(这更适合我的情况),然后 Run 函数变为 void 而不是返回一个对象,所以在调用之后我不能再转储对象了。
  • @JosephNasr,我很高兴能帮助你。虽然简单地传递 Actions 仍然有效,但使用 Expression&lt;Func&lt;T&gt;&gt; 的意图看起来很合理,参数传递几乎没有改进,... Run&lt;T&gt;(Expression&lt;Func&lt;T&gt;&gt;, params object[]? args) 这样我们可以使 linq 谓词(Delegates)也可以跨域工作!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 2022-01-26
  • 2018-11-17
  • 2017-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多