I am attempting to call an awaitable method via MethodInfo invoke.
The MethodInfo.Invoke() returns type object that needs to be cast as a Task before I can await it. If I manually cast the return type with a generic parameter of Task, the process works correctly.
However, I have a number of these methods to call that have different return types. How do I handle the return type?
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();
}
}
}
I can get the return type easily from cacheableMethod.ReturnType property. How can I do the cast dynamically? Without the cast, I cannot await the invocation.
I have tried casting simply as Task which of course does not work (EDIT: It does work). I have tried passing all of the parameters into a new generic method, but if I do not specify the generic type must be a Task (where T : Task), I get a compile time error that there is no definition for 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();
}
Thank you
With many thanks to Jon Skeet, was able to determine that the issue was the fact that I was making the cast too specific.
var resultTask = (Task) cachableMethod.Invoke(...)
allows the MethodInfo invocation to be awaited.