Answered by:
HttpClient Single Instance

Question
-
User439975351 posted
I have been reading several articles about the best way to use HttpClient. One article suggests a single instance in the Global.asax file. Does anyone have a definitive answer as to whether this is the best way to implement? The example code in the article is:
using System.Net; using System.Net.Http; using System.Web.Http; namespace HttpClientGuidance { public class WebApiApplication : System.Web.HttpApplication { internal static HttpClient httpClientInstance; protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); httpClientInstance = new HttpClient(); httpClientInstance.DefaultRequestHeaders.ConnectionClose = false; ServicePointManager.FindServicePoint ("some uri").ConnectionLeaseTimeout = 60 * 1000; ServicePointManager.FindServicePoint ("some other uri").ConnectionLeaseTimeout = 60 * 1000; ServicePointManager.FindServicePoint ("some other other uri").ConnectionLeaseTimeout = 60 * 1000; //etc..... } } }
Thursday, July 18, 2019 4:30 PM
Answers
-
User1724605321 posted
Hi 1jus,
You can create in Global.asax . A Singleton HttpClient does not respect DNS changes .Re-using an instance of HttpClient means that it holds on to the socket until it is closed so if you have a DNS record update occurring on the server the client will never know until that socket is closed . One easy workaround is to set the keep-alive header to false so the socket will be closed after each request, this obviously results in sub-optimal performance but if you do not care , or you can set the `ConnectionLeaseTimeout ` which specifies how long (in ms) the TCP socket can stay open :
ServicePointManager.FindServicePoint(endpoint) .ConnectionLeaseTimeout = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;
You can also need to reduce the DNS cache timeout which we can do by setting the DnsRefreshTimeout on the ServicePointManager class like :
ServicePointManager.DnsRefreshTimeout = (int)1.Minutes().TotalMilliseconds;
Best Regards,
Nan Yu
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, July 23, 2019 5:22 AM
All replies
-
User475983607 posted
The standard .NET documentation covers HttpClient in detail and includes recommended patterns.
https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netframework-4.8
This code snippet copied from the docs is perfectly fine.
public class GoodController : ApiController { // OK private static readonly HttpClient HttpClient; static GoodController() { HttpClient = new HttpClient(); } }
Other options are a Singleton pattern with one Singleton for each service consumed.
Dependency inject which is the standard in ASP.NET Core.
Thursday, July 18, 2019 4:57 PM -
User439975351 posted
Thanks mgebhard,
So would you say that the placement in global.asax would make sense for application wide usage? Also, do you have any suggestions regarding stale DNS/DNS caching?
Friday, July 19, 2019 7:50 AM -
User1724605321 posted
Hi 1jus,
You can create in Global.asax . A Singleton HttpClient does not respect DNS changes .Re-using an instance of HttpClient means that it holds on to the socket until it is closed so if you have a DNS record update occurring on the server the client will never know until that socket is closed . One easy workaround is to set the keep-alive header to false so the socket will be closed after each request, this obviously results in sub-optimal performance but if you do not care , or you can set the `ConnectionLeaseTimeout ` which specifies how long (in ms) the TCP socket can stay open :
ServicePointManager.FindServicePoint(endpoint) .ConnectionLeaseTimeout = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;
You can also need to reduce the DNS cache timeout which we can do by setting the DnsRefreshTimeout on the ServicePointManager class like :
ServicePointManager.DnsRefreshTimeout = (int)1.Minutes().TotalMilliseconds;
Best Regards,
Nan Yu
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, July 23, 2019 5:22 AM -
User439975351 posted
Thanks Nan Yu :)
Wednesday, July 24, 2019 8:11 AM