AsyncTimeout acts differently

Jun 2, 2012 at 12:53 PM

I am not sure if I get the usage of the AsyncTimeout action filter right. Here is my code:

    public class HomeController : Controller {

        [HandleError(ExceptionType = typeof(TimeoutException), View = "TimeoutError")]
        public async Task<ActionResult> Foo() {

            using (HttpClient client = new HttpClient()) {
                ViewBag.Status = await client.GetStringAsync("http://localhost:2098/Home/Wait");

            return View();

        public string Wait() {

            return "Foo";

The web request took at least 3 seconds to complete as you can see that I am hanging the thread. So, I should get a timeout exception when I hit the /Home/Foo (at least this is what I understood from AsyncTimeoutAttribute) but request completes successfully every time.

I tried this with ASP.NET MVC 4 RC.

Jun 2, 2012 at 6:08 PM

For Task-returning methods, the attribute controls only the delay period of the CancellationToken that is passed into the action method. For more information about cancellation of Tasks see [1]



Jun 2, 2012 at 6:38 PM

Ok, now that makes all sense. It should have been something like following:

        [HandleError(ExceptionType = typeof(TimeoutException), View = "TimeoutError")]
        public async Task<ActionResult> Foo(CancellationToken cancellationToken) {

            using (HttpClient client = new HttpClient()) {
                await client.GetAsync("http://localhost:2098/Home/Wait", cancellationToken);

            return View();

Jun 2, 2012 at 7:41 PM
Edited Jun 2, 2012 at 7:42 PM

BTW, is there any specific reason why HttpClient.GetStringAsync method doesn't accept CancellationToken? It is not hard to provide it as extension method but I thought you guys would unless there is a specific reason.

Jun 2, 2012 at 8:04 PM

The way to cancel HTTP requests is to cancel them on the HttpClient directly. The reason being that multiple requests can reuse TCP connections within a single HttpClient and so you can't safely cancel a single request without possibly affecting other requests as well.

You can control the timeout for requests -- I think it's on the HttpClientHandler if I recall correctly.

Hope this helps,


Jun 2, 2012 at 8:27 PM
Edited Jun 2, 2012 at 8:27 PM

Thanks for the information Henrik. But GetAsync has an overload method which accepts a CancellationToken. on the other hand, only specific ones don't have that such as GetStringAsync and GetStreamAsync. 

I played with a bit and modified the original code a bit. Here are the extension methods: Is that something worth keeping it around?

Also, providing a Timeout value for the request achieves the goal as you suggested.