Using the Task Async/Await pattern for grabbing data can be a real performance enhancement. When you thread off the calls, it’s pretty normal to want Task return objects to be in one single usable collection. The example I can give is a method that needs to gather up several different categories of lookup items. These calls all return a collection of the same type.
When you await the tasks, you generally have a few options:
Await each item individually
List<Task<List<LuItem>>> _allLus = new();
List<LuItem> _return = new();
_allLus.Add(LookupsSvc.GetLuItemsByCatShortNameAsync("URLTYPES"));
_allLus.Add(LookupsSvc.GetLuItemsByCatShortNameAsync("RVFUELTYPES"));
_allLus.Add(LookupsSvc.GetLuItemsByCatShortNameAsync("GENERATORFUELTYPES"));
Task<List<LuItem>>.WaitAll(_allLus.ToArray());
List<LuItem> _task1 = await _allLus[0];
List<LuItem> _task2 = await _allLus[1];
List<LuItem> _task3 = await _allLus[2];
_return.AddRange(_task1);
_return.AddRange(_task2);
_return.AddRange(_task3);
return _return;
Not sure how you feel, but this is horrible. I’m sure I’ve done something like this in the past, but I’d prefer not to think about it.
Use WhenAll to retrieve them in an Array
The Task.WhenAll, when declared with a type, will return an array of the return type. So in this case, it would return an Array of List<LuItem>. We can then do a simple LINQ query to push them all into one collection.
List<Task<List<LuItem>>> _allLus = new();
List<LuItem> _return = new();
_allLus.Add(LookupsSvc.GetLuItemsByCatShortNameAsync("URLTYPES"));
_allLus.Add(LookupsSvc.GetLuItemsByCatShortNameAsync("RVFUELTYPES"));
_allLus.Add(LookupsSvc.GetLuItemsByCatShortNameAsync("GENERATORFUELTYPES"));
List<LuItem>[] _await = await Task<List<LuItem>>.WhenAll(_allLus);
_await.ToList().ForEach(lus => _return.AddRange(lus));
return _return;
In this example, we await the Task with WhenAll, which has a return type, as opposed to WaitAll which does not. As stated earlier, this example will return a collection as Task<List<LuItem>[]>. So we’re most of the way there. We use the ToList().ForEach LINQ query to transform the Array of Lists into a single list called _return.\