I want to run an operation that should timeout after n milliseconds. I've implemented it two ways, one by cancelling the operation myself after waiting n milliseconds, and one by passing in a CancellationToken set to expire after n milliseconds.
I'm worried that as my system goes under heavy load, the cancellationtoken could expire before the operation even starts. It seems that if I implement the timeout myself using Task.Delay(), then the Delay() call won't run until after my operation begins.
Here's how I'm doing it:
public static async Task<T> TimeoutAfter<T>(this Task<T> task, TimeSpan timeout)
{
Task completedTask = await Task.WhenAny(task, Task.Delay(timeout));
if (completedTask == task)
{
return await task;
}
throw new TimeoutException();
}
// Use it like this
await SomeOperationAsync().TimeoutAfter(TimeSpan.FromMilliseconds(n));
Compared to:
CancellationTokenSource source = new CancellationTokenSource(TimeSpan.FromMilliseconds(n));
await SomeOperationAsync(source.Token);
See Question&Answers more detail:os