Convert a dictionary of tasks into a dictionary of results
Why didn't the await keyword work in my first example?
The await
keyword unwraps the Task<T>
within the context of an async
method, operates on the underlying result of type <T>
, and wraps the async
method's return value back in a Task
. That is why every async
method/function returns one of void
, Task
, or Task<T>
(note that void
is only appropriate for events). An async
method does not return an unwrapped value; we never see a method signature like public async int SomeMethod()
, because returning int
would not compile in an async
method. It would need to return a Task<int>
instead.
What is the right way to do this?
Here is one approach (with a Fiddle) to converting a dictionary with values of type Task<T>
to a dictionary with values of type <T>
:
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public async static void Main()
{
// create a dictionary of 10 tasks
var tasks = Enumerable.Range(0, 10)
.ToDictionary(i => i, i => Task.FromResult(i * i));
// await all their results
// mapping to a collection of KeyValuePairs
var pairs = await Task.WhenAll(
tasks.Select(
async pair =>
new KeyValuePair<int, int>(pair.Key, await pair.Value)));
var dictionary = pairs.ToDictionary(p => p.Key);
System.Console.WriteLine(dictionary[2].Value); // 4
}
}