You’re doing HttpClient wrong

Today I learned something that shocked me to my core. The following piece of c# code is wrong:

using (var client = new HttpClient()) {
   // client.GetAsync(...);
}

Why is this wrong?

Superficially, HttpClient implements IDisposable, and if you’re like me (and I suspect 90% of all .Net developers) you’ve been taught to diligently call Dispose() on anything that implements IDisposable.

Except that HttpClient is a bit different, it’s actually designed to be a shared object, and thread-safe.  If you come up against problems with TCP socket exhaustion, you’ve probably got loads of connections in TIME_WAIT state, and it could be due to this simple issue.  The use of HttpClient in a using block is so common across the internet, and in Microsoft’s documentation that it was a real shock that this was wrong.

What should I do instead?

You can instead just instantiate HttpClient once, either as a class-level static, or pass it around in your IoC container.  You could come up against some issues with setting properties such as Timeout after instantiation, and it may not respect changes to DNS but if you’re having problems with using too many sockets this is the only solution.

References:

https://stackoverflow.com/questions/15705092/do-httpclient-and-httpclienthandler-have-to-be-disposed

https://docs.microsoft.com/en-gb/azure/architecture/antipatterns/improper-instantiation/

Leave a Reply

Your email address will not be published. Required fields are marked *