How can I tell when HttpClient has timed out?

I am reproducing the same issue and it's really annoying. I've found these useful:

HttpClient - dealing with aggregate exceptions

Bug in HttpClient.GetAsync should throw WebException, not TaskCanceledException

Some code in case the links go nowhere:

var c = new HttpClient();
c.Timeout = TimeSpan.FromMilliseconds(10);
var cts = new CancellationTokenSource();
try
{
    var x = await c.GetAsync("http://linqpad.net", cts.Token);  
}
catch(WebException ex)
{
    // handle web exception
}
catch(TaskCanceledException ex)
{
    if(ex.CancellationToken == cts.Token)
    {
        // a real cancellation, triggered by the caller
    }
    else
    {
        // a web request timeout (possibly other things!?)
    }
}

You need to await the GetAsync method. It will then throw a TaskCanceledException if it has timed out. Additionally, GetStringAsync and GetStreamAsync internally handle timeout, so they will NEVER throw.

string baseAddress = "http://localhost:8080/";
var client = new HttpClient() 
{ 
    BaseAddress = new Uri(baseAddress), 
    Timeout = TimeSpan.FromMilliseconds(1) 
};
try
{
    var s = await client.GetAsync();
}
catch(Exception e)
{
    Console.WriteLine(e.Message);
    Console.WriteLine(e.InnerException.Message);
}