210

In all the examples I can find of usages of HttpClient, it is used for one off calls. But what if I have a persistent client situation, where several requests can be made concurrently? Basically, is it safe to call client.PostAsync on 2 threads at once against the same instance of HttpClient.

I am not really looking for experimental results here. As a working example could simply be a fluke (and a persistent one at that), and a failing example can be a misconfiguration issue. Ideally I'm looking for some authoritative answer to the question of concurrency handling in HttpClient.

Jim Aho
12k19 gold badges60 silver badges95 bronze badges
asked Jun 24, 2012 at 14:22
1

3 Answers 3

214

According to Microsoft Docs, since .NET 4.5 The following instance methods are thread safe (thanks @ischell):

CancelPendingRequests
DeleteAsync
GetAsync
GetByteArrayAsync
GetStreamAsync
GetStringAsync
PostAsync
PutAsync
SendAsync
PatchAsync
Martin Schneider
15.4k8 gold badges61 silver badges64 bronze badges
answered Jun 24, 2012 at 14:25
15
  • 3
    Yeah, I wasn't sure about that one, as it appears to be a standard warning on everything on MSDN (and I remember reading some MSDN blogs about how sometime that warning is wrong, as it is applied blindly to everything).
    Alex K
    Commented Jun 24, 2012 at 14:28
  • 3
    This is wrong; in the remarks section of the MSDN page you linked, it says that GetAsync, PostAsync, etc. are all thread safe.
    ischell
    Commented Jan 3, 2013 at 20:47
  • 4
    @ischell: I can assure you that the paragraph in question was not there at the time this issue was discussed.
    Marcel N.
    Commented Jan 3, 2013 at 22:05
  • 8
    So Microsoft have designed HttpClient to be reusable but then the class has instance data for headers: client.DefaultRequestHeaders.Accept.Add(...);
    cwills
    Commented Jun 11, 2014 at 8:12
  • 14
    In late, but I wanted to comment on @cwills. DefaultRequestHeaders are just that, defaults. If you want different headers on a per-request-basis, you can create new StringContent(), set additional headers on that, then use the overload that takes URI and HttpContent. Commented Nov 21, 2017 at 16:10
108

Here is another article from Henrik F. Nielsen about HttpClient where he says:

"The default HttpClient is the simplest way in which you can start sending requests. A single HttpClient can be used to send as many HTTP requests as you want concurrently so in many scenarios you can just create one HttpClient and then use that for all your requests."

answered Nov 15, 2012 at 23:44
10
  • 14
    What about if the username and password can change in between threads? that's what i can't seem to find anyone talking about Commented Nov 5, 2016 at 0:46
  • 1
    @NicholasDiPiazza: how often does it change? If there's a known set of user/password pairs then you can create a pool of HttpClient instances.
    Marcel N.
    Commented Jun 23, 2017 at 11:57
  • 4
    Note that reusing the same HttpClient for all your requests might result in stale DNS issues: github.com/dotnet/corefx/issues/11224. Commented Jul 6, 2017 at 21:52
  • 1
    @OhadSchneider If believe that issue is limited to .net core. You can fix the issue with .net 4 by injecting a custom HttpClientHandler into the HttpClient constructor then setting the "ConnectionLeaseTimeout". However, if no requests are sent to the endpoint for 100 seconds the connection will refresh on its own. protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,CancellationToken cancellationToken) { var sp = ServicePointManager.FindServicePoint(request.RequestUri); sp.ConnectionLeaseTimeout = 100 * 1000; } Commented Oct 4, 2017 at 14:13
  • 1
    @xr280xr simple answer: yes, disposing it will quickly exhaust your TCP sockets under load. Long answer: it's complex, and no one really knows the right way to use it. aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong stackoverflow.com/a/15708633/825588 nimaara.com/beware-of-the-net-httpclient learn.microsoft.com/en-us/azure/architecture/antipatterns/…
    Johann
    Commented Apr 21, 2021 at 23:03
23

Found one MSDN forum post by Henrik F. Nielsen (one of HttpClient's principal Architects).

Quick summary:

  • If you have requests that are related (or won't step on eachother) then using the same HttpClient makes a lot of sense.

  • In genral I would recommend reusing HttpClient instances as much as possible.

xr280xr
13.4k9 gold badges88 silver badges133 bronze badges
answered Jun 25, 2012 at 14:29
1
  • One important thing to consider for reusability: do fundamental settings of the client such as the timeout change in between calls? In my case, I refactored my code to reuse HttpClients a lot, only to find out the user may no longer update the custom timeout value in my app's settings, because after the first request was made you can no longer adjust the Timeout property. That wasn't an issue when I was creating new clients with the current timeout value from the settings.
    LWChris
    Commented Sep 19, 2024 at 13:04

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.