async TaskTimeoutAsyncTask (Func task, Func timeOutTask, int timeoutMilliseconds) { ... }
Have you noticed that .net’s MVC framework allows you to handle async action timeouts easily?
AsyncTimeoutAttribute
But the older (I think) WebAPI does not have such a nice way of handling this.
Here’s a bit of code to enable it:
public abstract class BaseController : ApiController {
protected async Task<T> TimeoutAsyncTask<T>(Func<T> task, Func<T> timeOutTask, int timeoutMilliseconds)
{
Task timeout = TimeoutTask(timeoutMilliseconds);
T result = default(T);
CancellationTokenSource cts = new CancellationTokenSource();
HttpContext current = HttpContext.Current; //preserve context
Task real = Task.Run(() => {
HttpContext.Current = current;
result = task.Invoke();
}, cts.Token);
Task finishedTask = await Task.WhenAny(timeout, real);
if (finishedTask == timeout){
//timeout
HttpContext.Current = current;
cts.Cancel();
result = timeOutTask.Invoke();
}
return result;
}
private async Task TimeoutTask(int timeoutValue)
{
await Task.Delay(timeoutValue);
}
}
So, to use this you could create a controller based from this (or just take the methods), and then call TimeoutAsyncTask(..) supplying two lambda functions to run. The first being the thing that you expect may take some time, and the 2nd being the callback function to run should the quantity of milliseconds pass before your task is complete. Either way, this async function will wait until either the supplied task is finished, or the timeout occurs (if called with await of course).
Great post mate! You saved me hours of work