异步 MethodInfo 调用 - 动态转换 return 类型
Async MethodInfo Invoke - cast return type dynamically
我正在尝试通过 MethodInfo 调用来调用可等待的方法。
MethodInfo.Invoke() returns 类型对象需要先转换为任务,然后才能等待它。如果我使用 Task 的通用参数手动转换 return 类型,该过程将正常工作。
但是,我有许多这些方法可以调用,它们具有不同的 return 类型。如何处理 return 类型?
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 属性 得到 return 类型。我怎样才能动态地进行转换?没有演员表,我无法等待调用。
我试过将其简单地转换为 Task,这当然行不通(编辑:它确实有效)。我已经尝试将所有参数传递给一个新的泛型方法,但如果我没有指定泛型类型必须是一个任务(其中 T :任务),我会收到一个编译时错误,指出没有 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();
}
谢谢
非常感谢 Jon Skeet,他能够确定问题出在我让演员表过于具体这一事实。
var resultTask = (Task) cachableMethod.Invoke(...)
允许等待 MethodInfo 调用。
答案已经发布:
var resultTask = (Task)cachableMethod.Invoke(...)
但是,请注意:
- 除了
Task
和 Task<T>
之外,您还可以 await on anything,因此如果您的下游方法 returns 可以使用扩展方法等待的内容,则该方法不会工作。
- 问题编号 1 可能是未来 C# 7 功能中的问题,其中 you can return a custom awaitable type 在异步方法中除了
Task
或 Task<T>
我正在尝试通过 MethodInfo 调用来调用可等待的方法。
MethodInfo.Invoke() returns 类型对象需要先转换为任务,然后才能等待它。如果我使用 Task 的通用参数手动转换 return 类型,该过程将正常工作。
但是,我有许多这些方法可以调用,它们具有不同的 return 类型。如何处理 return 类型?
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 属性 得到 return 类型。我怎样才能动态地进行转换?没有演员表,我无法等待调用。
我试过将其简单地转换为 Task,这当然行不通(编辑:它确实有效)。我已经尝试将所有参数传递给一个新的泛型方法,但如果我没有指定泛型类型必须是一个任务(其中 T :任务),我会收到一个编译时错误,指出没有 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();
}
谢谢
非常感谢 Jon Skeet,他能够确定问题出在我让演员表过于具体这一事实。
var resultTask = (Task) cachableMethod.Invoke(...)
允许等待 MethodInfo 调用。
答案已经发布:
var resultTask = (Task)cachableMethod.Invoke(...)
但是,请注意:
- 除了
Task
和Task<T>
之外,您还可以 await on anything,因此如果您的下游方法 returns 可以使用扩展方法等待的内容,则该方法不会工作。 - 问题编号 1 可能是未来 C# 7 功能中的问题,其中 you can return a custom awaitable type 在异步方法中除了
Task
或Task<T>