在主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中实例化的类型调用/等待异步方法...有没有方法?
谢谢!
答案 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); });