C# – Should we create a new single instance of HttpClient for all requests

chttp-request

recently I came across this blog post from asp.net monsters which talks about issues with using HttpClientin following way:

using(var client = new HttpClient())
{
}

As per the blog post, if we dispose the HttpClient after every request it can keep the TCP connections open. This can potentially lead to System.Net.Sockets.SocketException.

The correct way as per the post is to create a single instance of HttpClient as it helps to reduce waste of sockets.

From the post:

If we share a single instance of HttpClient then we can reduce the waste of sockets by reusing them:

namespace ConsoleApplication
{
    public class Program
    {
        private static HttpClient Client = new HttpClient();
        public static void Main(string[] args)
        {
            Console.WriteLine("Starting connections");
            for(int i = 0; i<10; i++)
            {
                var result = Client.GetAsync("http://aspnetmonsters.com").Result;
                Console.WriteLine(result.StatusCode);
            }
            Console.WriteLine("Connections done");
            Console.ReadLine();
        }
    }
}

I have always disposed HttpClient object after using it as I felt this is the best way of using it. But this blog post now makes me feel I was doing it wrong all this long.

Should we create a new single instance of HttpClient for all requests? Are there any pitfalls of using static instance?

Best Answer

It seems like a compelling blog post. However, before making a decision, I would first run the same tests that the blog writer ran, but on your own code. I would also try and find out a bit more about HttpClient and its behavior.

This post states:

An HttpClient instance is a collection of settings applied to all requests executed by that instance. In addition, every HttpClient instance uses its own connection pool, isolating its requests from requests executed by other HttpClient instances.

So what is probably happening when an HttpClient is shared is that the connections are being reused, which is fine if you don't require persistent connections. The only way you're going to know for sure whether or not this matters for your situation is to run your own performance tests.

If you dig, you'll find several other resources that address this issue (including a Microsoft Best Practices article), so it's probably a good idea to implement anyway (with some precautions).

References

You're Using Httpclient Wrong and It Is Destabilizing Your Software
Singleton HttpClient? Beware of this serious behaviour and how to fix it
Microsoft Patterns and Practices - Performance Optimization: Improper Instantiation
Single instance of reusable HttpClient on Code Review
Singleton HttpClient doesn't respect DNS changes (CoreFX)
General advice for using HttpClient