This post collects some usage guidelines for
HttpClient that may not be obvious.
Per MSDN, “
HttpClient is intended to be instantiated once and re-used throughout the life of an application.” The rationale is mentioned in that MSDN article and described in detail in this blog post.
HttpClient methods for making HTTP requests are thread-safe, so as long as you don’t change any of its properties (
Timeout, etc.) after you start making requests, reusing the same instance on any thread will be fine.
The simplest way to reuse
HttpClient instances is to create a static readonly field in the class that needs to make HTTP requests. Of course, that still results in one instance per class, so consider allowing the
HttpClient instance to be specified via constructor or method parameter.
HttpClient is disposable, but there’s no harm in never disposing it if it is used for the life of the application.
SendAsync method is the most flexible way to send an HTTP request with
HttpClient. It accepts an
HttpRequestMessage and returns an
HttpResponseMessage. Note that both classes are disposable; be sure to dispose of instances of both classes when you are finished with them.
Example: FacilityCSharp has tests that run a number of HTTP requests in a row that
POST a JSON body and process a JSON result. After a few dozen requests,
HttpClient would asynchronously deadlock. I never got to the bottom of it, but I did find a solution: dispose the HTTP requests and responses.
When an HTTP request times out, an
OperationCanceledException exception is thrown, not a
The default timeout is 100 seconds. If you are using a single HttpClient instance (see above), you’ll want to make sure that
HttpClient.Timeout is set as high as any request might need.
To use a shorter timeout for certain requests, use
CancellationTokenSource.CancelAfter and send in the corresponding cancellation token. If you already have a cancellation token, use
CancellationTokenSource.CreateLinkedTokenSource and call
CancelAfter on that. If you need to distinguish between the two types of cancellation, check if the original cancellation token is cancelled.
Example: This StackOverflow answer demonstrates combining a cancellation token and a timeout.
Apparently you can use
ServicePoint.ConnectionLeaseTimeout to work around this problem (see linked articles).
Aside: FacilityCSharp does not address this problem, but if you’re a Facility user and experience it, please file an issue and let us know!
Posted by Ed Ball on March 30, 2017