There are several scenarios where I need to invoke multiple asynchronous calls (from the same event handler) that can proceed independently of each other, with each one having its own continuation for updating the UI.
The following naive implementation causes the three asynchronous operations to be executed sequentially:
private async void button_Click(object sender, RoutedEventArgs e)
{
nameTextBox.Text = await GetNameAsync();
cityTextBox.Text = await GetCityAsync();
rankTextBox.Text = await GetRankAsync();
}
There's an MSDN example that suggests separating the creation of the tasks from their respective await statements, allowing them to be run in parallel:
private async void button_Click(object sender, RoutedEventArgs e)
{
var nameTask = GetNameAsync();
var cityTask = GetCityAsync();
var rankTask = GetRankAsync();
nameTextBox.Text = await nameTask;
cityTextBox.Text = await cityTask;
rankTextBox.Text = await rankTask;
}
However, the limitation of this approach is that the task continuations are still registered sequentially, meaning that the nth continuation can't execute before all its preceding n−1 continuations have completed, even though its task may be the first to complete.
What is the best pattern for getting the asynchronous tasks to run in parallel, but have each continuation run as soon as its respective task completes?
Edit: Most of the answers suggest awaiting on Task.WhenAll
, like below:
private async void button_Click(object sender, RoutedEventArgs e)
{
var nameTask = GetNameAsync();
var cityTask = GetCityAsync();
var rankTask = GetRankAsync();
await Task.WhenAll(nameTask, cityTask, rankTask);
nameTextBox.Text = nameTask.Result;
cityTextBox.Text = cityTask.Result;
rankTextBox.Text = rankTask.Result;
}
However, this does not meet my requirement, as I need each continuation to execute as soon as its respective task completes. For example, suppose that GetNameAsync
takes 5 s, GetCityAsync
takes 2 s, and GetRankAsync
takes 8 s. The implementation above would cause all three textboxes to only be updated after 8 s, even though the results for nameTextBox
and cityTextBox
were known much earlier.