Async MethodInfo Invoke - 动态转换返回类型

时间:2016-09-19 19:42:34

标签: c# asynchronous expression system.reflection

我试图通过MethodInfo调用调用一个等待的方法 MethodInfo.Invoke()返回需要在等待它之前转换为Task的类型对象。如果我使用通用参数Task手动转换返回类型,则该过程可以正常工作。

但是,我有许多这些方法可以调用具有不同返回类型的方法。我该如何处理退货类型?

public class Repository
{
    public IEnumerable<Foo> GetListAsync(int criteria)
    {
        return new List<Foo> {new Foo {Bar = "1"}, new Foo {Bar = "2"}};
    }
}

public class Foo
{
    public string Bar { get; set; }
}

public class Precache
{
    public static void RegisterPreCache(Repository instanceObject)
    {

        var preCachedType = typeof (Repository);

        var preCachableMethods =
            preCachedType
                .GetMethods();

        foreach (var cachableMethod in preCachableMethods)
        {
            var resultTask =
                (Task<IEnumerable<Foo>>) cachableMethod.Invoke(instanceObject,
                    new object[]
                    {1});
            Task.Run(async () => await resultTask).Wait();
        }
    }
}

我可以从cacheableMethod.ReturnType属性轻松获取返回类型。如何动态进行演员表?没有演员表,我无法等待调用。

我试过简单地将其作为任务当然不起作用(编辑:它确实有效)。我已经尝试将所有参数传递给一个新的泛型方法,但如果我没有指定泛型类型必须是一个Task(其中T:Task),我得到一个编译时错误,没有GetAwaiter的定义。

private static void CallExpression<T>(T returnType, MethodInfo     
    cachableMethod, object instanceObject, object[] parameters) 
{
    var resultTask = (T) cachableMethod.Invoke(instanceObject, parameters);
    Task.Run(async () => await resultTask).Wait();
}

谢谢

2 个答案:

答案 0 :(得分:4)

非常感谢Jon Skeet,能够确定问题是因为我使演员过于具体。

var resultTask = (Task) cachableMethod.Invoke(...)  

允许等待MethodInfo调用。

答案 1 :(得分:1)

答案已经发布:

var resultTask = (Task)cachableMethod.Invoke(...)  

但是,请注意:

  1. 除了TaskTask<T>之外,您还可以await on anything,因此如果您的下游方法返回了可以通过扩展方法等待的内容,那么该方法将无效。
  2. 问题编号1在将来的C#7功能中可能会出现问题,除TaskTask<T>
  3. 之外的异步方法中you can return a custom awaitable type