Run async work with a hard timeout
C#
using System;
using System.Threading;
using System.Threading.Tasks;
/// <summary>Awaits a task but throws when it exceeds a deadline.</summary>
public static class TimeoutExtensions
{
public static async Task<T> WithTimeoutAsync<T>(
this Task<T> task,
TimeSpan timeout,
CancellationToken cancellationToken = default)
{
using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cts.CancelAfter(timeout);
try
{
// WaitAsync releases the await when the task or the token completes.
return await task.WaitAsync(cts.Token);
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
throw new TimeoutException($"operation exceeded {timeout.TotalMilliseconds:0} ms");
}
}
public static async Task Main()
{
var slow = Task.Delay(TimeSpan.FromSeconds(5)).ContinueWith(_ => 42);
try
{
Console.WriteLine(await slow.WithTimeoutAsync(TimeSpan.FromMilliseconds(100)));
}
catch (TimeoutException e)
{
Console.WriteLine(e.Message); // operation exceeded 100 ms
}
}
}