Async WebAPI Timeouts

async Task TimeoutAsyncTask(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).

Comments ( 1 )

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>