Reputation: 3735
I'm trying to run tasks async by using reflection. The problem is that the class is abstract. I got this to work with InvokeMember
in a synchronous context. With async the method is not found for some reason.. So this is what I came up with instead. It's not working because I can't pass an object of an abstract class to the Invoke method.. dead end?
public MyClass
{
public async Task<string> MyMethod()
{
var tasks = new List<Task>();
for (int i = 0; i < 3; i++)
{
string taskType = "Banana"; // should be an array[i]
Type type = Type.GetType("MyService." + taskType);
var method = type.GetMethod("Test");
var result = (Task<string>)method.Invoke(null, null);
tasks.Add(result);
}
await Task.WhenAll(tasks);
}
}
And for example the 'taskType' above is a class which looks like this:
public abstract class Banana
{
public async Task<string> Test(string input)
{
await Task.Delay(5000);
return "foo";
}
}
Upvotes: 1
Views: 543
Reputation: 5384
We've discussed this in the comments, but maybe the following code gives you a better idea.
public class MyClass
{
public async Task<string> MyMethod()
{
var tasks = new List<Task>();
for (int i = 0; i < 3; i++)
{
string taskType = "Banana"; // should be an array[i]
Type type = Type.GetType("MyService." + taskType);
var method = type.GetMethod("Test");
var result = (Task)method.Invoke(null, null);
tasks.Add(result);
}
await Task.WhenAll(tasks);
var theResult = string.Empty;
foreach(var task in tasks)
{
theResult += (string)task.GetType().GetProperty("Result").GetValue(task);
}
return theResult;
}
}
I've written it completely blind and couldn't test it - bear with me!
But the general idea is the following: the concrete async method is of Task<string>
, but I couldn't find a way to invoke an async generic method. But since every Task<T>
is a non-generic Task
, we can cast to it and await it. The additional knowledge that each element within tasks
is a Task<string>
allows us to retrieve its property Result
via reflection.
Upvotes: 2