I am trying to process each async task result when/as they complete. These tasks have different result sets. I like to execute these tasks concurrently but need to process the result when any finishes.
There are many google search results when async functions have the same return type, however, I couldn't get my hand to one with different result sets.
private async Task CompleteTasksAsync()
{
var taskA = GetStringAsync();
var taskB = GetIntAsync();
var taskC = GetStringListAsync();
var taskD = GetGenericAsync<double>(1d);
//var tasks = new[] {taskA, taskB, taskC, taskD} // this will only work if all
// tasks have same return type
await Task.WhenAll(taskA, taskB, taskC, taskD); // This statement will wait
// until all tasks are completed
// when Task A finished Console.WriteLine(taskA.Result);
// when Task B finished Console.WriteLine(taskB.Result);
// when Task C finished Console.WriteLine(taskC.Result);
// when Task D finished Console.WriteLine(taskD.Result);
}
private Task<string> GetStringAsync() => Task.FromResult("string");
private Task<int> GetIntAsync() => Task.FromResult(1);
private Task<List<string>> GetStringListAsync()
=> Task.FromResult(new List<string> { "string"});
private Task<T> GetGenericAsync<T>(T data) => Task.FromResult(data);
Finally, For anyone who want to do it without the if/switch
. I used Dictionary<TAsk, Action>
and this helped me to shape the tasks and results.
private async Task CompleteTasksAsync()
{
var taskA = GetStringAsync();
var taskB = GetIntAsync();
var taskC = GetStringListAsync();
var taskD = GetGenericAsync<double>(1d);
Dictionary<Task, Action> tasks = new()
{
{taskA, () => Console.WriteLine(taskA.Result)},
{taskB, () => Console.WriteLine(taskB.Result) }, {taskC, () => Console.WriteLine(taskC.Result) },
{taskD, () => Console.WriteLine(taskD.Result) }
};
while (tasks.Any())
{
var completedTask = await Task.WhenAny(tasks.Keys);
tasks[completedTask]();
tasks.Remove(completedTask);
}
}