Reputation: 8903
I've read a lot of conflicting answers about this and still don't have it straight. I have a .net core 1.1 web app that hits a lot of external api's for various data sources. My curent implementation uses DI to pass a custom "webclient" class to each controller, which internally creates and disposes a httpclient for each request (inside a using block). I see a ton of idle connections on the server so I'm pretty sure this is causing these. I also have some issues with the .net core app crashing and no longer responding, so I'm wondering if too many connections open is creating this problem.
I realize that httpclient can be reused for many connections, but I'm not clear on several things. I've read that reusing the same httpclient is really more useful for thick client apps and not as useful with web apps due to the very parallel nature of the web requests. I've also read that you want to cache the same httpclient for reuse for a distinct URL, but my url's use querystrings to pass parameters, so would this not mean that every fully qualitified URL is unique from the others?
My idea is to possibly cache a single instance of httpclient for each base domain name of the api's I am accessing, but I haven't found confirmation if this would give the benefits I'm looking for with using a single httpclient instance. I assume my goal is to reuse idled connections, will this accomplish this?
I also came across a reference to a solution similar to what I'm doing that would cache these instances but then check if any of them have become disposed at some point and recreate them as needed.
Seems like this should be easy stuff but there is a ton of conflicting info out there!
Upvotes: 2
Views: 1247
Reputation: 1082
HttpClient can potentially stay opened during the lifetime of the application or longer, even though it does implement IDisposable. So you are on the right track with using a single instance of HttpClient, because you are guaranteed to only have one connection open at any time.
.NET Core has helper functions for DI. If you use the following a singleton instance of your webclient will be injected into all classes which consume it. This means that every class will be using the same instance of the webclient object, therefore use the same httpclient.
Use the following in your startup.cs ConfigureServices function:
services.AddSingleton<IWebClient>(new webclient(params));
or
services.AddSingleton<IWebClient, webclient>();
Singleton lifetime services are created the first time they're requested (or when ConfigureServices is run if you specify an instance there) and then every subsequent request will use the same instance. If your application requires singleton behavior, allowing the services container to manage the service's lifetime is recommended instead of implementing the singleton design pattern and managing your object's lifetime in the class yourself.
Microsoft documentation for DI in .NET Core
Upvotes: 1