{"id":8746,"date":"2022-03-16T21:38:27","date_gmt":"2022-03-16T21:38:27","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=8746"},"modified":"2022-03-16T21:38:27","modified_gmt":"2022-03-16T21:38:27","slug":"net-httpclient-the-correct-way-to-use-it","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/net-httpclient-the-correct-way-to-use-it\/","title":{"rendered":".NET HttpClient &#8211; the correct way to use it"},"content":{"rendered":"<p>For ages I&#8217;ve been using the HttpClient in .NET without any issues, but usually I have a single endpoint and a singleton (or equivalent) of a class that uses the HttpClient. A while back I needed to call multiple different endpoints using the HttpClient and so I happily wrapped an instantiation of an HttpClient in a using statement, I mean after all it has an IDisposable interface so that makes sense right?<\/p>\n<p>Well NO this is not the case. So don&#8217;t do this!<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\/\/ Don't do this\r\nusing(var httpClient = new HttpClient())\r\n{\r\n   \/\/ do something with httpClient\r\n}\r\n<\/pre>\n<p>This post stems from a work colleague pointing me to the post <a href=\"https:\/\/www.aspnetmonsters.com\/2016\/08\/2016-08-27-httpclientwrong\/\" rel=\"noopener\" target=\"_blank\">YOU&#8217;RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE<\/a>.<\/p>\n<p><strong>What does the documentation say?<\/strong><\/p>\n<p>If you take a look at the <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.net.http.httpclient?view=net-5.0\" rel=\"noopener\" target=\"_blank\">HttpClient Class<\/a> documentation states <\/p>\n<p><em>HttpClient is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors.<\/em><\/p>\n<p>If we take a look at some C# templates in Visual Studio, for example the ASP.NET core Blazor application template, it will give you a scoped instance of the HttpClient, for example<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nbuilder.Services.AddScoped(sp =&gt; \r\n  new HttpClient \r\n    { \r\n       BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) \r\n    }\r\n);\r\n<\/pre>\n<p><strong>So how are we supposed to use a single instance of HttpClient<\/strong><\/p>\n<p>Let&#8217;s now assume that we create an HttpClient per application. Then how do we call multiple service endpoints without having changes affect different endpoint calls and is it threadsafe?<\/p>\n<p>Is the HttpClient thread-safe? Well the answer is both yes and no. <\/p>\n<p>Changing properties on the HttpClient are not threadsafe or at least cannot\/should not be modified whilst there are outstanding requests. However methods such as GetAsync, PostAsync, SendAsync etc. are threadsafe which then leads us to how to se set-up different calls, i.e. maybe different headers etc. on all our calls. The answer here is to use SendAsync and create an HttpRequestMessage. This allows us to specify many of the properties we&#8217;ll need per HTTP call.<\/p>\n<p><strong>References<\/strong><\/p>\n<p><a href=\"https:\/\/www.aspnetmonsters.com\/2016\/08\/2016-08-27-httpclientwrong\/\" rel=\"noopener\" target=\"_blank\">YOU&#8217;RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE<\/a><br \/>\n<a href=\"https:\/\/www.stevejgordon.co.uk\/httpclient-creation-and-disposal-internals-should-i-dispose-of-httpclient\" rel=\"noopener\" target=\"_blank\">HTTPCLIENT CREATION AND DISPOSAL INTERNALS: SHOULD I DISPOSE OF HTTPCLIENT?<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For ages I&#8217;ve been using the HttpClient in .NET without any issues, but usually I have a single endpoint and a singleton (or equivalent) of a class that uses the HttpClient. A while back I needed to call multiple different endpoints using the HttpClient and so I happily wrapped an instantiation of an HttpClient in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[49,3],"tags":[],"class_list":["post-8746","post","type-post","status-publish","format-standard","hentry","category-net","category-c"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8746","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=8746"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8746\/revisions"}],"predecessor-version":[{"id":9299,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8746\/revisions\/9299"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=8746"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=8746"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=8746"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}