如何使用反射调用C#中的异步方法并且不会导致死锁?

And*_*Cui 1 .net c# asynchronous async-await

我想通过Task<T>类型反射实例调用异步方法,我使用了Task.WaitAlland .GetAwaiter().GetResult(),但它们都会导致死锁。我现在该怎么办?

例如:

给定

async Task<T> Add<T>(T model); 
Run Code Online (Sandbox Code Playgroud)

我就是这样做的

void InvokeByReflection(object model) { 
    MethodInfo method = typeof(SAMPLE).GetTypeInfo().GetMethod("Add"); 
} 
Run Code Online (Sandbox Code Playgroud)

如何在没有死锁的情况下调用方法?

zai*_*man 6

目前尚不清楚反射与死锁有何关系。调用异步方法非常简单:

关键 - 这里需要异步:

async void InvokeByReflection(SAMPLE sample, object model) { 
   await (Task)typeof(SAMPLE)
       .GetTypeInfo()
       .GetMethod("Add")
       .MakeGenericMethod(new []{model.GetType()})
       .Invoke(sample, new object[]{ model }); 
} 
Run Code Online (Sandbox Code Playgroud)

或者,如果您在网络中使用完整的 .Net Framework,请不要忘记.ConfigureAwait(false);(这对于 .Net Core 不再重要,因为 Kestrel 在线程池而不是主线程上分派所有请求)。

更新以获取结果:

    async void InvokeByReflectionAndgetResult(SAMPLE sample, object model) { 
     var task =(Task)typeof(SAMPLE)
     .GetTypeInfo()
     .GetMethod("Add")
     .MakeGenericMethod(new []{model.GetType()})
     .Invoke(sample, new object[]{ model }); 
     await task;
     var result = task.GetType().GetProperty("Result").GetValue(task);
    } 
Run Code Online (Sandbox Code Playgroud)