Singleton HttpClient calling GetAsync / SendAsync with async / await never returns

I am creating an application using Xamarin (Android), it uses the PCL project as a service level. I have a Web Api endpoint and I use HttpClient to use it.

Everything works fine, but if I leave my Android application open and unoccupied for a while (for example, 2 minutes) and I try to make a new request, the first request using singleton HttpClient will not work. It just never returns and stays there until timeouts ( TaskCancelledException ). I also set a breakpoint on my Api and it didn’t hit. If I try to send the request again, it will work.

After a lot of debugging, I found that this only happens if I try to use HttpClient as a Singleton. If I create a new HttpClient for each request, everything will work.

At first I thought it was a dead end problem, I did a lot of research and double-checked everything, following the instructions described in this other answer , and Stephen Cleary is a great post , and I'm almost sure that it is not. I use ConfigureAwait(false) in every call from my PCL project, so it does not capture the context.

The request flow is as follows:

Inside the Android snippet:

 SampleService svc = new SampleService(); response = await svc.GetAllSamples(); 

Service called (in my PCL project):

 public class SampleService { public HttpClient Client { get; set; } public SampleService() { // resolves my singleton instance and uses my custom DelegatingHandler Client = CustomHttpClient.Instance; } public async Task<IEnumerable<Sample>> GetAllSamples() { IEnumerable<Sample> list = null; // this never returns and timeouts the first time using (var response = await Client.GetAsync("samples").ConfigureAwait(false)) { if (response.IsSuccessStatusCode) { string json = await response.Content.ReadAsStringAsync().ConfigureAwait(false); lista = await Task.Run(() => JsonConvert.DeserializeObject<IEnumerable<Sample>>(json)).ConfigureAwait(false); } return list; } } } 

This is how I create an instance of Singleton:

 public sealed class CustomHttpClient { private static HttpClient _client; public static HttpClient GetClient() { if (_client == null) { HttpMessageHandler messageHandler = new HttpClientHandler(); _client = new HttpClient(messageHandler); _client.Timeout = TimeSpan.FromSeconds(30); _client.BaseAddress = new Uri("myendpoint"); _client.DefaultRequestHeaders.Accept.Clear(); _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); } return _client; } } 

I tried to simplify and isolate the code here, if I can provide any other useful snippets, just let me know.

Am I doing something wrong with HttpClient singletones that I don't know about?

Update: For explanatory HttpClient only, I am trying to use HttpClient as Singleton only because, as I found in this answer by Darrell Miller and in the book Designing the Evolvable Web API Using ASP.NET (Chapter 14), they were designed to be reusable and thread-safe. safe (in most cases). From my research, I am not using anything that is not thread safe.

+6
source share

All Articles