【问题标题】:How to get await an array οf tasks (Task<T>[]) to become an array of things (T[])?如何让 await 一个任务数组(Task<T>[])变成一个事物数组(T[])?
【发布时间】:2021-10-17 07:41:19
【问题描述】:

这不是关于一般如何使用asyncawait 的问题。它考虑了一个我在文档中没有找到的非常具体的案例。

我有一个我不习惯的类型设置。通常,我将awaitTask&lt;Whatever&gt; 设置为最终将具有的类型。现在,我陷入了以下困境,经过一段时间的尝试,我意识到我不知道如何摆脱output 中的Task&lt;Thing&gt; 类型。我只希望它是Thing

Task<Thing>[] output = list.Select(async a => new Thing
{
    Id = a.Id,
    Name = a.Name,
    Props = (await SomeService.GetAsync(a))
      .Select(b => b.Value).ToArray()
}).ToArray();

要求output 的声明是明确的(即没有var)并且它不是异步的(即没有Task)。 output 的类型必须是Thing[],我不喜欢使用Task.WhenAll(output),因为它需要提前声明output,这违反了前两个要求。

需要内部await 才能应用Select。但这强加了外部async,因此使其成为事物的任务数组(即Task&lt;Thing&gt;[]),而不是事物的数组(即Thing[])。

我不能将await 放在列表前面,因为无法等待一系列任务。我不能把它放在lamba表达式中,因为它破坏了语法。

我已经对语法和示例进行了一些搜索,但这有点不常见,所以我发现没有什么价值。甚至可以做到吗?我相信它可以,但我不知道我们如何。我只找到this question。不过,它是相关的,但不够相似。而且答案实际上并没有显示如何实现我想要的(即在变量声明中消除了varTask)。

【问题讨论】:

    标签: c# .net-core async-await task-parallel-library


    【解决方案1】:

    我怀疑你正在寻找Task.WhenAll

    Thing[] result = await Task.WhenAll(output);
    

    为了避免必须在任何地方使用Task&lt;Thing&gt;[],或者将长表达式作为Task.WhenAll 的参数,您可以编写一个扩展方法:

    public static class TaskEnumerable
    {
        public static Task<T[]> WhenAllTasks<T>(this IEnumerable<Task<T>> tasks) =>
            Task.WhenAll(tasks);
    }
    

    您的代码可以是:

    Thing[] output = await list.Select(async a => new Thing
    {
        Id = a.Id,
        Name = a.Name,
        Props = (await SomeService.GetAsync(a))
          .Select(b => b.Value).ToArray()
    }).WhenAllTasks();
    

    【讨论】:

    • 有点。该选项要求声明output,并且该声明的类型是我不愿意var(全金属外壳OCD)的对象。而且团队不允许我使用“长”类型(由于他们的全金属外壳 OCD 针对Dictionary&lt;Dictionary&lt;KeyValuePair&gt;,...&gt;)。您是说这是唯一的方法(除了不声明 output 而是将完整表达式复制到 WhenAll 方法中)?在那种情况下,我更喜欢var... :)
    • @KonradViltersten:我不太明白你在问什么。您的问题不使用任何匿名类型,这通常是需要var 的地方 - 我已经回答了您的问题(等待Task&lt;Thing&gt;[] 得到Thing[])。您只在最后一句的括号中提到了var,没有在代码示例中的任何地方使用var。据我所知,我回答了您实际提出的问题 - 如果您想提出不同的问题,请在问题中澄清。
    • 抱歉不清楚。在我的示例中,我有Task&lt;Thing&gt;[],团队不喜欢它,因为他们不喜欢它,而是更喜欢使用var,我不喜欢它。不过,Thing[] 他们会很好,所以我正在努力想办法让每个人都开心。
    • @KonradViltersten:我建议你在这个问题中更加清楚。我想我可以用扩展方法解决这个问题。
    • 更新了问题,使其丰富现在更加清晰。
    猜你喜欢
    • 1970-01-01
    • 2015-02-12
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 2011-05-13
    相关资源
    最近更新 更多