Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert Dictionary<string, Task<int>> to Task<Dictionary<string, int>> [duplicate]

I am working on retrieving about 10 different types of data using http-requests with rather complex dependencies between them. And I am trying to find my way through this in an elegant, readable and maintainable way without waiting unnecessarily.

Let's assume, some method creates a Dictionary<string, Task<int>>. What is the most elegant way to convert this into Task<Dictionary<string, int>>?

The new outer Task should finish, as soon as all Tasks contained in the dictionary are finished.

Of course, I can write this manually:

Dictionary<string, Task<int>> values = GetValues();
Task<Dictionary<string, int>> result = Task.Run(async () => {
    Dictionary<string, int> rewrapped = new();
    foreach (var entry in values) {
        rewrapped.Add(entry.Key, await entry.Value);
    }
    return rewrapped;
});

But isn't there a better way?

like image 667
Andreas Avatar asked Apr 28 '26 11:04

Andreas


1 Answers

Rule of thumb: Never use Task.Run instead of it being truly async, it will use a thread to mimic asyncronity!

You just have to await the values, then get the Results:

Dictionary<string, Task<int>> values = GetValues();
await Task.WhenAll(values.Values);
Dictionary<string, int> results = values.ToDictionary(p => p.Key, p => p.Value.Result);

You can wrap the last two lines in a method, if you really want a Task<Dictionary<string, int>>.

async Task<Dictionary<string, int>> Unwrap(Dictionary<string, Task<int>> values)
{
    await Task.WhenAll(values.Values);
    return values.ToDictionary(p => p.Key, p => p.Value.Result);
}
like image 200
wertzui Avatar answered Apr 30 '26 00:04

wertzui



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!