tabs ↹ over ␣ ␣ ␣ spaces

by Jiří {x2} Činčura

TaskCanceledException on timeout on HttpClient

7 Jan 2013 C#, Lessons learned, Multithreading/Parallelism/Asynchronous/Concurrency

.NET Framework has a nice new class for all sort of HTTP stuff called HttpClient (interesting the name wasn’t taken before :)). And because it’s I/O related it has also bunch on XxxAsync methods to nicely fit into C# 5’s async/await.

So you might write code similar to this, based on experience based on previous “network” classes.

var client = new HttpClient();
client.Timeout = TimeSpan.FromMilliseconds(200); //adjust based on your network
try
{
	var result = await client.GetStringAsync("http://blog.cincura.net/");
}
catch (HttpRequestException)
{
	// handle somehow
	Console.WriteLine("HttpRequestException");
}
catch (TimeoutException)
{
	// handle somehow
	Console.WriteLine("TimeoutException");
}

If you try to run it, you’ll get unhandled exception, TaskCanceledException to be precise. Yep, the timeout is not propagated as TimeoutException, but as TaskCanceledException. It caught me off guard a little bit. The documentation for Timeout property touches CancellationTokenSource and you can feel the steer to TaskCanceledException. But, still, could be mentioned explicitly, will not be that surprising. Or maybe my thinking was skewed.

This code then works correctly.

var client = new HttpClient();
client.Timeout = TimeSpan.FromMilliseconds(200);
try
{
	var result = await client.GetStringAsync("http://blog.cincura.net/");
}
catch (HttpRequestException)
{
	// handle somehow
	Console.WriteLine("HttpRequestException");
}
//catch (TimeoutException)
//{
//	// handle somehow
//	Console.WriteLine("TimeoutException");
//}
catch (TaskCanceledException)
{
	// handle somehow
	Console.WriteLine("TaskCanceledException");
}