Home > Software engineering >  WaitAll for tasks from dictionary and get result, including Dictionary key
WaitAll for tasks from dictionary and get result, including Dictionary key

Time:03-29

I have to modify the following code. I have given a list of tasks (httpClient.Run method returns Task). I have to run them and wait until all of them are done. Later on I need to collect all results and build response.

var tasks = new Dictionary<string, Task<string>>);
tasks.Add("CODE1", service.RunTask("CODE1"));
tasks.Add("CODE2", service.RunTask("CODE2"));
tasks.Add("CODE3", service.RunTask("CODE3"));
...

var result = await Task.WhenAll(tasks.Values()); // how to get CODE (dictionary KEY) here
// build response

The problem above is that when we get results we have lost exactly which task was run. results is string array, but I need, for instance,KeyValuePair array. We need to know which task (CODE) was run, so that we can build result properly.

CodePudding user response:

Something like this ought to do it. This is written assuming you do the Task.WhenAll() call first. Otherwise, you'll block the thread when you start to enumerate over resultsWithKeys.

await Task.WhenAll(tasks.Values());
var resultsWithKeys = tasks.Select(
    x => new
    {
        Key = x.Key, 
        Result = x.Value.Result
    });

foreach (var result in resultsWithKeys)
    Console.WriteLine($"{result.Key} - {result.Result.SomeValue}");

CodePudding user response:

You have to loop through the finished tasks. You can do this two different ways:

var data = tasks.Values().Select(a => a.Result).ToList()

If you awaited them all like above, there is no problem calling .Result afterwards to get the data.

The other way you could do this is simply avoid the WhenAll and just handle each individually as it will end up doing the same thing in the end. Instead of WhenAll, just do this:

var list = new List<string>();
foreach (var keyPair in tasks)
{
   list.Add(await keyPair.Value);
{
  • Related