【问题标题】:Cross AppDomain async method call跨 AppDomain 异步方法调用
【发布时间】:2013-02-16 13:59:57
【问题描述】:

我试图从主 AppDomain 调用在不同 AppDomain 中实例化的类型中定义的异步方法。

例如,以下类型 MyClass 继承自 MarshalByRefObject 并在新的 AppDomain 中实例化:

public class MyClass : MarshalByRefObject
{
  public async Task<string> FooAsync()
  {
     await Task.Delay(1000);
     return "Foo";
  }
}

在主 AppDomain 中,我创建一个新的 AppDomain 并在此 AppDomain 中创建 MyClass 的一个实例,然后调用 async 方法。

var appDomain = AppDomain.CreateDomain("MyDomain");
var myClass = (MyClass)appDomain.CreateInstanceAndUnwrap(typeof(MyClass).Assembly.FullName, typeof(MyClass).FullName);
await myClass.FooAsync(); // BAM !

当然,当我尝试拨打电话时,我会得到一个SerializationException,因为Task 类型不是从MarshalByRefObject 继承的,也不是可序列化的。

我怎么能解决这个问题?我真的很希望能够从另一个 AppDomain 中实例化的类型调用/等待异步方法...有没有办法?

谢谢!

【问题讨论】:

  • 您可能会发现this question 很有帮助。
  • 这正是我所期待的优雅解决方案。谢谢斯蒂芬!!!
  • 在第二个 appdomain 中定义一个事件可能是一个解决方案。第一个 appdomain 在第二个 appdomain 中调用一个仅触发事件的方法,控制权返回到第一个 appdomain 并在第二个 appdomain 中继续执行事件。

标签: c# appdomain async-await


【解决方案1】:

我知道这个问题已有 7 年的历史,但万一有人觉得这有帮助:

如今,一个简单的解决方案可能是使用 Task.Run 调用同步方法并等待 Task.Run 方法。

而不是:

await RemoteObject.MethodAsync(); //Still throws a SerializationException.

用途:

await Task.Run(RemoteObject.Method); //If the method has no parameters.
await Task.Run(()=>RemoteObject.Method(parameter)); // If it does.

可以获取方法的返回值(如果不是void,且返回类型可以跨AppDomains):

var result = await Task.Run(RemoteObject.GetDefaultValue); // If the method has no parameters.
var result = await Task.Run(()=>RemoteObject.GetValue(parameter)); // If it does.

Task.Run 将在委托具有非 void 返回类型时隐式变为 Task.Run&lt;returnType&gt;(委托本身将变为 Func 而不是 Action)。如果您使用方括号来创建 lambda 表达式,那么您必须手动返回该方法的结果以暗示它是 Func 而不是 Action

var result = await Task.Run(()=>{ return RemoteObject.GetValue(parameter); });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 2015-11-28
    • 2020-01-17
    • 1970-01-01
    相关资源
    最近更新 更多