跨AppDomain异步方法调用

时间:2013-03-01 23:09:57

标签: c# appdomain async-await

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

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

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

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

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中实例化的类型调用/等待异步方法...有没有方法?

谢谢!

1 个答案:

答案 0 :(得分:0)

我知道这个问题已经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.

您可以获取该方法的返回值(如果它不是无效的,并且其返回类型可以跨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将隐式变为Task.Run<returnType>(委托本身将成为Func而不是Action)。如果使用方括号创建lambda表达式,则必须手动返回方法的结果,以暗示它是Func而不是Action

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