如何让await任务数组(Task<T>[])变成事物数组(T[])?
How to get await an array οf tasks (Task<T>[]) to become an array of things (T[])?
这不是一般如何使用 async
和 await
的问题。它考虑了一个我在文档中没有找到的非常具体的案例。
我有一个我不习惯的类型设置。通常,我把 await
和 Task<Whatever>
去任务化到它最终要有的类型。现在,我陷入了以下困境,经过一段时间的尝试,我意识到我不知道如何摆脱 output
中的 Task<Thing>
类型。我只希望它是 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<Thing>
[]),而不是事物数组(即Thing[]
)。
我不能将 await
放在列表前面,因为一组任务不可等待。我不能把它放在 lamba 表达式中,因为它破坏了语法。
我搜索了一些语法和示例,但这种情况有点不常见,所以我发现没什么价值。甚至可以做到吗?我相信它可以,但我不知道我们怎么做。我只找到了 this question。不过,它是相关的,但不够相似。而且答案实际上并没有显示如何实现我想要的(这是在变量声明中消除 var
和 Task
)。
我怀疑你在找 Task.WhenAll
:
Thing[] result = await Task.WhenAll(output);
为了避免必须在任何地方使用 Task<Thing>[]
,或将长表达式作为 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();
这不是一般如何使用 async
和 await
的问题。它考虑了一个我在文档中没有找到的非常具体的案例。
我有一个我不习惯的类型设置。通常,我把 await
和 Task<Whatever>
去任务化到它最终要有的类型。现在,我陷入了以下困境,经过一段时间的尝试,我意识到我不知道如何摆脱 output
中的 Task<Thing>
类型。我只希望它是 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<Thing>
[]),而不是事物数组(即Thing[]
)。
我不能将 await
放在列表前面,因为一组任务不可等待。我不能把它放在 lamba 表达式中,因为它破坏了语法。
我搜索了一些语法和示例,但这种情况有点不常见,所以我发现没什么价值。甚至可以做到吗?我相信它可以,但我不知道我们怎么做。我只找到了 this question。不过,它是相关的,但不够相似。而且答案实际上并没有显示如何实现我想要的(这是在变量声明中消除 var
和 Task
)。
我怀疑你在找 Task.WhenAll
:
Thing[] result = await Task.WhenAll(output);
为了避免必须在任何地方使用 Task<Thing>[]
,或将长表达式作为 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();