Task<IList<>> 作为 Func<> 的结果

Posted

技术标签:

【中文标题】Task<IList<>> 作为 Func<> 的结果【英文标题】:Task<IList<>> as a result of Func<> 【发布时间】:2013-11-28 09:08:26 【问题描述】:

我尝试使用 wrap 方法调用我的异步方法并进行一些额外的计算:

private async Task<IEnumerable<Dictionary<string, object>>> Execute(Func<Task<IList<Dictionary<string, object>>>> func)

  var ret = await func();
  // Skipped
  return ret;

它适用于某些情况:

var data = await Execute(() => chain.Start(parameters), args);

chain.Start 在哪里

async Task<IList<Dictionary<string, object>>> Start(Dictionary<string, object> parameters)

但在某些情况下,我的 func 是不可等待的,所以我尝试在其中返回 Task.FromResult。

var ret = Execute(() => Task.FormResult(new List<Dictionary<string, object>>());

编译器说,

错误 24 无法将 lambda 表达式转换为委托类型 'System.Func>>>' 因为块中的某些返回类型不是隐式的 可转换为委托返回类型

在这种情况下可以使用 awaitable 吗?或者我应该以同步的方式重写我的代码?

【问题讨论】:

[Offtopic] Dmytro,你是乌克兰人吗? 【参考方案1】:

问题在于Task&lt;T&gt; 不是协变的(也不能是协变的,因为它不是一个接口)。

所以写Task.FromResult(new List&lt;Dictionary&lt;string, object&gt;&gt;())时,FromResult的返回类型是Task&lt;List&lt;Dictionary&lt;string, object&gt;&gt;&gt;,不能转换成Task&lt;IList&lt;Dictionary&lt;string, object&gt;&gt;&gt;

解决方案是明确指定FromResult 泛型参数:

var ret = Execute(() => Task.FormResult<IList<Dictionary<string, object>>>(
    new List<Dictionary<string, object>>());

【讨论】:

以上是关于Task<IList<>> 作为 Func<> 的结果的主要内容,如果未能解决你的问题,请参考以下文章

IList<> 返回类型而不是 List<>

为啥 `IList<T>` 不从 `IReadOnlyList<T>` 继承?

如何序列化 IList<T>?

IList<T> 和 IReadOnlyList<T>

IList<T> 到 IQueryable<T>

将 IList<T> 转换为 BindingList<T>