I have a Android Xamarin Forms application, and I am trying to set a timeout for an HttpClient using a CancellationToken, but it doesn't appear to be working. The request seems to time out after about 2 minuntes as opposed to the 5 seconds I expect:
private HttpClient _httpClient = new HttpClient(new HttpClientHandler() { UseProxy = false })
{
Timeout = TimeSpan.FromSeconds(5)
};
public async Task<T> GetAsync<T>(string url, TimeSpan timeout) where T : new()
{
using (var tokenSource = new CancellationTokenSource(timeout))
{
try
{
using (var response = await _httpClient.GetAsync(url, tokenSource.Token))
{
// never gets here when it times out on a bad address.
response.EnsureSuccessStatusCode();
using (var responseStream = await response.Content.ReadAsStreamAsync())
{
if (response.IsSuccessStatusCode)
{
using (var textReader = new StreamReader(responseStream))
{
using (var jsonReader = new JsonTextReader(textReader))
{
return JsonSerializer.CreateDefault().Deserialize<T>(jsonReader);
}
}
}
else
{
return default(T);
}
}
}
}
catch (TaskCanceledException)
{
// this gets hit after about 2 minutes as opposed to the 5 seconds I expected.
return default(T);
}
catch
{
return default(T);
}
}
}
And then usage:
var myObject = await GetAsync<MyObject>("https://example.com/badRequest", TimeSpan.FromSeconds(5));
If I run this same code from a .NET Core application, it works as I would expect (timing out in 5 seconds).
Does anybody have any idea why the Mono framework is ignoring the cancellation token and what a reasonable workaround would be?