Wait on a Task with a timeout

Nov 22, 2025  

I’ve lost count of how many times I wrote code like this to implement a timeout on an asynchronous operation that doesn’t support cancellation.

1var task  = ...
2var delay = Task.Delay(timeout);
3var finalTask = await Task.WhenAny(task, delay);
4
5if (finalTask == task)
6{
7    await task;
8}

A built-in solution in .NET

The Task class provides since .NET 6 a method which does exactly what I need:

1var task = ...
2await task.WaitAsync(TimeSpan.FromMilliseconds(timeout));

Much cleaner, and there a several overloads available:

  • WaitAsync(CancellationToken)
  • WaitAsync(TimeSpan)
  • WaitAsync(TimeSpan, CancellationToken)

There are even variants accepting a TimeProvider, which makes testing easier.
Combined with FakeTimeProvider, you can test timeouts without relying on real delays.

Note: If you already have a CancellationToken for the operation, prefer the overload that combines timeout + token to avoid layering multiple cancellation paths.