一般调用Task <t>方法</t>

时间:2014-12-02 12:21:26

标签: c# generics async-await task

Casting TResult in Task<TResult> to System.Object相关。我正在为服务构建一个通用的异步命令执行函数。

执行通用命令的方法如下所示:

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

代码使用反射来查找具有给定cmdName的类的方法。调用此方法将返回Type<T> - 我们事先不知道T。但是,由于Task<T>不是协变的,我无法转换为Task<object>

目前我的解决方案(根据21805564)是调用Result方法并封装在Task.Run中,如下所示:

// 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); });

我担心这样做会否定异步的价值:获得结果现在是一个阻塞调用,所以我不妨使用同步方法。

2 个答案:

答案 0 :(得分:5)

您可以等待任务,然后在完成后反映结果

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

或者:

return ((dynamic)t).Result;

答案 1 :(得分:5)

请记住dynamic可用。只要您不使用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;
}

特别是,我建议不要使用Task.Run因为这会浪费一个帖子,我不建议使用Task.Result,因为它会封装AggregateException内的所有异常1}}。