3

i making ~20 http get requests using one httpclient, this httpclient is long living, means it is not packed into a using statement. As the webservice is normally pretty fast (response time ~200ms) i set the timeout to 5sec.

Now i ran into the problem, if one request runs into that timeout all other requests get cancelled. Is this the normal behaviour?

Here is the code i am using to make conccurent calls

public async Task GetAll()
{
    await Task.WhenAll(x => x.Select(xx => GetData(xx.Id));
}

Code to call the api:

    public async Task GetData(int id)
    {
        string payload = "";
        try
        {
            var resp = await base.GetAsync($"/apis/v2/getdata/{id}");
            if (!resp.IsSuccessStatusCode)
                Console.WriteLine("Error");

            payload = await resp.Content.ReadAsStringAsync();
            Console.WriteLine(payload);
        }
        catch (System.Exception ex)
        {
            Console.WriteLine("Error");
        }
    }

My Base HttpClient Class

public class MyHttpClient : System.Net.Http.HttpClient
{
    public Logger Log  { get; set; }
}

If i run the task in sequential order everything works fine, but when i run them in parallel and one task runs into a timeout all other not finished task will be cancelled.

8
  • This can't be your actual code. For a start, it wouldn't even compile because it's missing the async modifier. What is base here? What does base.GetAsync do? Commented Jul 9, 2019 at 12:31
  • If set ServicePointManager.DefaultConnectionLimit to 20, would that fix the issue? ( because default limit is 2 in .Net Framework, reference : blogs.msdn.microsoft.com/timomta/2017/10/23/… ) Commented Jul 9, 2019 at 12:32
  • 1
    @Stefan D'oh, I didn't see it was 2 distinct functions. Still, we need to know what base is, not sure how you think it is an HttpClient (base is a reserved word so it cannot be a variable name) Commented Jul 9, 2019 at 12:39
  • @DavidG GetData is a method in my HttpClient Class which simply derives from System.Net.HttpClient, so base.GetAsync only calls the System.Net.HttpClient.GetAsync method. I have not tried the DefaultConnectionLimit. I first wanted to understand how the HttpClient behaves if one request times out while others are still running. Commented Jul 9, 2019 at 12:39
  • @ManuelBleimuth there's a default limit of 2 concurrent connections per domain, enforced by all browsers and .NET itself. You can overwrite in the HttpClientHandler settings. On the other hand, it may be the API that's blocking due to blocking database connections, locks or inefficient coding. Commented Jul 9, 2019 at 12:42

1 Answer 1

2

If any of the supplied tasks completes in a faulted state, the returned task will also complete in a Faulted state, where its exceptions will contain the aggregation of the set of unwrapped exceptions from each of the supplied tasks.

Source: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=netframework-4.8

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.