Summary: in this tutorial, you’ll learn how to use the C# WhenAny()
static method of the Task
class to create a task that will complete when any of the input tasks have been completed.
Introduction to the C# WhenAny() method
The Task.WhenAny()
is a static method of the Task
class that allows you to wait for the first task in a collection of tasks to complete.
When a task completes, the Task.WhenAny()
returns a Task<T>
object that represents the completed task.
To use the Task.WhenAny()
method, you follow these steps:
- First, pass a collection of tasks to the method.
- Second, use the
await
keyword to wait for any of the tasks in the collection to complete. - Third, assign the completed task to a variable and use the
await
keyword again to get the result.
The C# WhenAny()
method is useful when you have to make multiple HTTP requests to different APIs and process the first result.
For example, suppose you have an app that displays the latest news from multiple sources, each source has an API.
To display the news as soon as possible, you can use the Task.WhenAny()
method to wait for the first API request to complete, display the news and continue fetching the news from other APIs in parallel.
A simple C# WhenAny() method example
The following example demonstrates how to use the WhenAny()
method:
static async Task<int> DoWork(int number, int ms)
{
await Task.Delay(ms);
return number;
}
var t1 = Task.Run(() => DoWork(1, 1000));
var t2 = Task.Run(() => DoWork(2, 500));
Task<int> completedTask = await Task.WhenAny(t1, t2);
int result = await completedTask;
Console.WriteLine(result);
Code language: JavaScript (javascript)
How it works.
First, define the DoWork()
method that accepts two parameters: number
, an integer, and ms
, a number of milliseconds. The method returns the number
after a delay of ms
milliseconds:
static async Task<int> DoWork(int number, int ms)
{
await Task.Delay(ms);
return number;
}
Code language: JavaScript (javascript)
Second, create two tasks t1
and t2
using the Task.Run()
method. The tasks execute the DoWork()
method with different parameters:
t1
callDoWork(1,1000)
that delays for1000
milliseconds before returning the number1
.t2
callDoWork(2,500)
that delays for500
milliseconds before returning the number2
.
var t1 = Task.Run(() => DoWork(1, 1000));
var t2 = Task.Run(() => DoWork(2, 500));
Code language: JavaScript (javascript)
Third, use the Task.WhenAny()
method to wait for either t1
or t2
to complete, whichever finishes first. When one of the tasks completes, the Task.WhenAny()
method returns a Task<int>
object that represents the completed task.
Task<int> completedTask = await Task.WhenAny(t1, t2);
int result = await completedTask;
Code language: JavaScript (javascript)
Fourth, use the await
keyword to wait for the Task<int>
object to complete and assign the result to completedTask
variable:
int result = await completedTask;
Code language: JavaScript (javascript)
Finally, output the result to the console:
Console.WriteLine(result);
Code language: CSS (css)
Practical use of the C# WhenAny() method
The following program attempts to download two images from different URLs and saves the first one using the C# WhenAny() method:
// Define the URLs of the two images
string url1 = "https://via.placeholder.com/600/771796";
string url2 = "https://via.placeholder.com/600/24f355";
// Create two tasks to request the two images asynchronously
HttpClient client = new();
var t1 = client.GetByteArrayAsync(url1);
var t2 = client.GetByteArrayAsync(url2);
// Wait for the first task to complete
var completedTask = await Task.WhenAny(t1, t2);
// Save the result of the first task to a file
byte[] bytes = await completedTask;
string fileName = "image.jpg";
File.WriteAllBytes(fileName, bytes);
Console.WriteLine($"The picture has been saved to {fileName}");
Code language: JavaScript (javascript)
How it works.
First, define the URLs of the two images to download:
string url1 = "https://via.placeholder.com/600/771796";
string url2 = "https://via.placeholder.com/600/24f355";
Code language: JavaScript (javascript)
Second, create a new instance of the HttpClient
class to make HTTP requests:
HttpClient client = new();
Code language: C# (cs)
Third, create two tasks that download the two pictures asynchronously. The GetByteArrayAsync()
method returns a Task<byte[]>
object:
var t1 = client.GetByteArrayAsync(url1);
var t2 = client.GetByteArrayAsync(url2);
Code language: C# (cs)
Fourth, use the Task.WhenAny() method to wait for the first task to complete:
var completedTask = await Task.WhenAny(t1, t2);
Code language: C# (cs)
Finally, save the result of the first task into a file:
byte[] bytes = await completedTask;
string fileName = "image.jpg";
File.WriteAllBytes(fileName, bytes);
Console.WriteLine($"Saved the picture to {fileName}");
Code language: C# (cs)
Summary
- Use the C#
WhenAny()
method to wait for the first task in a collection of tasks to finish.