Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

197
Views
Why using HttpClient in a using block IS WRONG in WebApi context?

So, the question is why the usage of HttpClient in using block is WRONG, BUT in WebApi context?

I've been reading this article Don't Block on Async Code. In it we have the following example:

public static async Task<JObject> GetJsonAsync(Uri uri)
{
  // (real-world code shouldn't use HttpClient in a using block; this is just example code)
  using (var client = new HttpClient())
  {
    var jsonString = await client.GetStringAsync(uri);
    return JObject.Parse(jsonString);
  }
}

// My "top-level" method.
public class MyController : ApiController
{
  public string Get()
  {
    var jsonTask = GetJsonAsync(...);
    return jsonTask.Result.ToString();
  }
}

The comment // (real-world code shouldn't use HttpClient in a using block; this is just example code) just triggered me. I've been always using HttpClient in this way.

The next thing I've checked is Microsoft's documentation on HttpClient Class. In it, we have the following statement with provided source sample:

HttpClient is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors. Below is an example using HttpClient correctly.

public class GoodController : ApiController
{
    private static readonly HttpClient HttpClient;

    static GoodController()
    {
        HttpClient = new HttpClient();
    }
}

So isn't the constructor called on each request and thus a new HttpClient will be created every time?

Thanks!

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

There's a bit of a long answer to this...

Originally, the official recommendation was to use HttpClient in a using block. But this caused problems at scale, essentially using up lots of connections in the TIME_WAIT state.

So, the official recommendation changed to use a static HttpClient. But this caused problems where it would never correctly handle DNS updates.

So, the ASP.NET team came up with IHttpClientFactory in .NET Core 2.1, so code (or at least code running on modern platforms) can reuse HttpClient instances (or, more properly, the message handlers of those instances), avoiding the TIME_WAIT problem, but also periodically closing those connections to avoid the DNS problem.

But, at the same time, the .NET team came up with SocketsHttpHandler also in .NET Core 2.1, which also does connection pooling.

So, on modern platforms, you can either use IHttpClientFactory or a static/singleton HttpClient. On older platforms (including .NET Framework), you would use a static/singleton HttpClient and either live with the DNS issue or use other workarounds.

over 4 years ago · Santiago Trujillo Report

0

Actually writing this question I noticed the static constructor in the code sample provided from Microsoft. This all makes sense now.

The Static Constructors are used to initialize any static data, or to perform a particular action that needs to be performed only once. It is called automatically before the first instance is created or any static members are referenced.

In the context of WebAPI the static constructor is called one time only thus creating only one HttpClient and reusing it for all other requests.

I'll never use using(HttpClient....) in production code again.

This is a great article on the wrong usage of HttpClient - YOU'RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!