Calling <T> Methods in General

Related to Running TResult in Task <TResult> in System.Object . I am creating a generic async command function for a service.

The method for executing the general command is as follows:

public async Task<object> ExecuteCommandAsync(string cmdName, CommandData data)

The code uses reflection to find the method for the class that has the given cmdName. The challenge of this returns Type<T>- we do not know Tin advance. However, since it is Task<T>not covariant, I cannot use Task<object>.

My current solution (according to 21805564) is to call the Result method and encapsulate in Task.Run, as shown below:

// find the method
MethodInfo cmd = GetMethod(cmdName);
var task = (Task)cmd.Invoke(this, data);
return await Task.Run<object>(() => { return task.GetType().GetProperty("Result").GetValue(task); });

My concern is that doing this negates the async value: getting the result is now a blocking call, so I could also use synchronous methods.

+4
source share
2 answers

Remember what dynamicis available. You can do something like this if you don't use Microsoft.Bcl.Async:

public async Task<dynamic> ExecuteCommandAsync(string cmdName, CommandData data)
{
  MethodInfo cmd = GetMethod(cmdName);
  dynamic task = cmd.Invoke(this, data);
  return await task;
}

In particular, I do not recommend using Task.Runit because it will waste the stream, and I do not recommend using Task.Resultit because it will encapsulate any exceptions inside AggregateException.

+5
source

You can wait for the task, and then think about the result after it is completed.

public static async Task<object> AwaitResult(Task t)
{
    await t;
    return t.GetType().GetProperty("Result").GetValue(t, null);
} 

Or:

return ((dynamic)t).Result;
+5
source

All Articles