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

时间:2017-04-15 13:19:23

标签: c# .net asynchronous async-await

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

例如:

给出

async Task<T> Add<T>(T model); 

我就是这样做的

void InvokeByReflection(object model) { 
    MethodInfo method = typeof(SAMPLE).GetTypeInfo().GetMethod("Add"); 
} 

如何调用没有死锁的方法?

1 个答案:

答案 0 :(得分:2)

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

严重 - 需要异步此处:

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

或者,如果您使用完整的.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);
    }