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; } }
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.
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?
What about this:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With