Task-based Asynchronous Pattern – WithTimeout

The same way we in CCR sometimes wanted to add a timeout to an existing "task" you probably want to do the same in TAP. So here are two extension methods you could use to add a timeout to any task of your choice:

 1: public async static Task WithTimeout(this Task task, TimeSpan timeout)
 2: {
 3:     var cancelationSource = new CancellationTokenSource();
 4:     var delay = Task.Delay(timeout, cancelationSource.Token);
 5:     await Task.WhenAny(task, delay);
 6:     if (task.IsCompleted)
 7:     {
 8:         cancelationSource.Cancel();
 9:     }
 10:     else
 11:     {
 12:         throw new TimeoutException();
 13:     }
 14: }
 16: public async static Task<T> WithTimeout<T>(this Task<T> task, TimeSpan timeout)
 17: {
 18:     await ((Task)task).WithTimeout(timeout);
 19:     return await task;
 20: }
Comments (2)

  1. Sean Hanna says:

    Don't timeouts normally stop the asynchronous operation, so these extension methods are only 'ad-hoc' in that they wait for a set period of time?

  2. A timeout in its simplest form is just a way to stop waiting on the calling side. The actual work is only "stopped" if the work actually executing supports cancellation. Think about the case where you send a request to another web server and that server starts an infinite loop, never sending any data back. There is no way you can stop that infinite loop from the client side. In these extension methods you're just extending an existing task and as such you cannot stop it. You might be temted to try and kill the thread the task is running on but that is a bad idea since killing a thread hard does not do proper cleanup if needed.

Skip to main content