【问题标题】:How to evaluate a list of tasks如何评估任务列表
【发布时间】:2020-06-19 04:05:46
【问题描述】:

我有 2 个实体:Topic.csLecture.cs、一个模型:TopicModel.cs 和一个异步 repo 调用 repo.GetAllLecturesAsync(string topicId)。这些内容很直观。

我需要异步从 repo 类中获取所有讲座并将它们放入主题模型中。我有以下代码:

List<TopicModel> topicModels = topics.Select(async topic => new TopicModel
{
    Lectures = (await repo.GetAllLecturesAsync(topic.Id)).ToList()
}).ToList();

此代码生成以下错误:

"Cannot implicitly convert type 'List<Task<TopicModel>>' to 'List<TopicModel>'"

如何去掉中间的Task

编辑:

topicsList&lt;Topic&gt; 的一种。

GetAllLecturesAsync() 返回Task&lt;IEnumerable&lt;Lecture&gt;&gt;

TopicModel 有一个属性public List&lt;Lecture&gt; Lectures{ get; set; }

【问题讨论】:

  • 尝试类似(未经测试)Lectures = (await repo.GetAllLecturesAsync(topic.Id)).Select(task =&gt; task.Result).ToList()
  • 你的想法是对的,你只需要在第一次选择之后添加 .Select(task => task.Result) 像这样: List topicModels = topics.Select(async topic => new TopicModel { Lectures = (await repo.GetAllLecturesAsync(topic.Id)).ToList() }).Select(task => task.Result).ToList();修正你的答案,我会接受的。
  • 我很困惑为什么你需要额外的ToList()ToList()IEnumerable&lt;T&gt; 扩展方法,Select() 也是如此。您应该能够在任何您调用 ToList() 上调用 Select() 并避免枚举 IEnumerable&lt;T&gt;,直到您需要在最后将其转换为列表。
  • 哦,我现在明白了,我的困惑是因为您没有指出线路被抛出的位置,我认为它来自属性分配。现在修正我的答案。
  • 删除了我的答案。我对 async / await 的理解不足以提供足够的答案。我认为您的代码存在缺陷,我无法识别并认为它只是类型不匹配。试图用你的建议来修正我的答案只会增加混乱。

标签: c# linq async-await


【解决方案1】:

你可以使用Task.WhenAll:

TopicModel[] topicModels = await Task.WhenAll(topics
    .Select(async topic => new TopicModel
    {
        Lectures = (await repo.GetAllLecturesAsync(topic.Id)).ToList()
    }));

默认情况下Task.WhenAll 返回一个数组,但如果需要List,您可以在结果上调用ToList

【讨论】:

  • 这是正确的。但是,这个调用是在几个 select 语句中。当我尝试将其应用于我的代码时,我最终得到了 3 个额外的 await Task.WhenAll 和 2 个现有的非异步表达式变得异步,这使得代码看起来像一团糟。 @Jacob Huckins 的方法更加面向对象友好。不管怎么说,多谢拉。我很高兴知道这一点。
  • @M.Azyoksul 你能把整个 sn-p 放在某个地方吗?
  • 我不想让你迷失在细节中,所以here 是一个足够详细的版本。
猜你喜欢
  • 2020-07-18
  • 2019-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-24
  • 1970-01-01
  • 1970-01-01
  • 2012-05-25
相关资源
最近更新 更多