Consuming rest api timeout

How to deal with timeout problem when calling REST service. My GetAsync function:

    private async Task<string> GetAsync(string endPoint, string id)
    {
        using (var httpClient = new HttpClient())
        {
            SevenMResultNx<string> result = new SevenMResultNx<string>(false);

            httpClient.BaseAddress = new Uri(baseAddress);
            httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
            httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(token);

            // HTTP GET
            HttpResponseMessage response = await httpClient.GetAsync(String.Format("{0}/{1}", endPoint, id));
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsStringAsync();
            }
            else
            {
                return response.ReasonPhrase;
            }
        }
    }

is called like:

        Task<string> task = GetAsync(endPoint, id);
        var responseGet = task.Result;

Whenever endpoint is unavaiable, I got problem because process waits infinity.

Jon Skeet
people
quotationmark

I would suggest making your method accept a CancellationToken that you can then pass onto the GetAsync and ReadAsStringAsync methods.

You can easily create a cancellation token which will expire after a certain time:

var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1));
var text = await GetAsync(endpoint, id, cts.Token);

In addition, using Result in the caller is almost certainly a mistake. It means if you're using a scheduler that has a single thread, you'll deadlock - your thread will be waiting for the task to complete, but it won't be able to complete because when the httpClient.GetAsync call completes, it needs to execute more code in the same thread. Two improvements:

  • In your GetAsync method, where you're awaiting tasks, use ConfigureAwait(false) as you probably don't care which thread the rest of the async method continues on
  • Make the calling code asynchronous as well, and await the returned task.

people

See more on this question at Stackoverflow