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
CancellationTokenfor the operation, prefer the overload that combines timeout + token to avoid layering multiple cancellation paths.