变换的IEnumerable&LT;任务&LT; T&GT;&GT;异步地等待每个任务 [英] Transform IEnumerable<Task<T>> asynchronously by awaiting each task
问题描述
今天,我想知道如何等待每次它变换的任务列表。
请看下面的例子:
Today I was wondering how to transform a list of Tasks by awaiting each of it. Consider the following example:
private static void Main(string[] args)
{
try
{
Run(args);
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadLine();
}
}
static async Task Run(string[] args)
{
//Version 1: does compile, but ugly and List<T> overhead
var tasks1 = GetTasks();
List<string> gainStrings1 = new List<string>();
foreach (Task<string> task in tasks1)
{
gainStrings1.Add(await task);
}
Console.WriteLine(string.Join("", gainStrings1));
//Version 2: does not compile
var tasks2 = GetTasks();
IEnumerable<string> gainStrings2 = tasks2.Select(async t => await t);
Console.WriteLine(string.Join("", gainStrings2));
}
static IEnumerable<Task<string>> GetTasks()
{
string[] messages = new[] { "Hello", " ", "async", " ", "World" };
for (int i = 0; i < messages.Length; i++)
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
tcs.SetResult(messages[i]);
yield return tcs.Task;
}
}
我想改变我的任务列表,而不在foreach,但无论是匿名函数的语法,也不是通常的函数语法允许我做我的foreach做什么。
I'd like to transform my list of Tasks without the foreach, however either the anonymous function syntax nor the usual function syntax allows me to do what my foreach does.
我必须依靠我的foreach和列表&LT; T&GT;
或有没有什么办法让它与的IEnumerable&LT工作; T&GT ;
及其所有优点
Do I have to rely on my foreach and the List<T>
or is there any way to get it to work with IEnumerable<T>
and all its advantages?
推荐答案
这个是什么:
await Task.WhenAll(tasks1);
var gainStrings = tasks1.Select(t => t.Result).ToList();
等待所有任务的结束,然后提取结果。这是理想的,如果你不介意的次序,他们就完成了。
Wait for all tasks to end and then extract results. This is ideal if you don't care in which order they are finished.
EDIT2:
更好的方法:
Even better way:
var gainStrings = await Task.WhenAll(tasks1);
这篇关于变换的IEnumerable&LT;任务&LT; T&GT;&GT;异步地等待每个任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!