{"id":238,"date":"2017-07-02T18:07:49","date_gmt":"2017-07-02T18:07:49","guid":{"rendered":"http:\/\/www.dimlucas.com\/?p=238"},"modified":"2019-04-26T13:53:46","modified_gmt":"2019-04-26T13:53:46","slug":"using-the-httpclient-the-correct-way","status":"publish","type":"post","link":"https:\/\/www.dimlucas.com\/index.php\/2017\/07\/02\/using-the-httpclient-the-correct-way\/","title":{"rendered":"Using the HttpClient the correct way"},"content":{"rendered":"<p>The other day I was building a small demo ASP.NET Core 2.0 application for the purposes of a video course I&#8217;m preparing on the upcoming second version of .NET Core.<\/p>\n<p>The application was making several http requests to third party APIs. I noticed that it was taking unusually long to finish. At first I thought that something was wrong with the preview version of .NET Core and curious to find out why I ported it to the stable .NET Core 1.1 and started filling the code with stopwatches to discover the source of the lag. <\/p>\n<p>What I found out was that I have been using the HttpClient all wrong. And probably so do you. All the countless C# books, tutorials and courses out there all mention that the correct usage of the HttpClient is withing a &#8221;using&#8217; statement.<\/p>\n<p>The flow of this thought goes something like this: The HttpClient holds unmanaged resources, it also implement the IDisposable interface. When it comes to other IDisposables like the StreamReader we wrap them in &#8216;using&#8217; statements so we should do the same with HttpClient. <\/p>\n<p>The problem is, that&#8217;s not the case! Creating a new instance of the HttpClient every time we make a request and disposing it after the request completes is not the most sensible thing to do as it turns out. You&#8217;re better off having a single HttpClient instance. You can achieve this by creating a wrapper for the HttpClient and either declare it as static or register it as a singleton with your preferred IoC container. The second solution seems more elegant and avoids the static cling code smell.<\/p>\n<p>But let&#8217;s take it from the beginning. After the discovering what made my application so slow, I figured I could run a test. So I created a .NET Core Console Applciation from scratch. I then went on to creating two classes, the SlowWay and the FastWay static classes. (I know, awful names). Both classes make several requests to this url: http:\/\/jsonplaceholder.typicode.com\/photos.<\/p>\n<p>The SlowWay classes follows the famous &#8216;using&#8217; convention. The FastWay class uses the same HttpClient for all requests<\/p>\n<p><script src=\"https:\/\/gist.github.com\/dimlucas\/09a649175ed21288a172187a5427061a.js\"><\/script><\/p>\n<p><script src=\"https:\/\/gist.github.com\/dimlucas\/d2ba4e64f623372f6500bad2a321ba29.js\"><\/script><\/p>\n<p>And here&#8217;s how I tested them:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/dimlucas\/2049e3ee1aaf0083f0c1b87d7b862d35.js\"><\/script><\/p>\n<p>With the RequestCount set to 30 I got the following results:<\/p>\n<p><img loading=\"lazy\" src=\"https:\/\/www.dimlucas.com\/wp-content\/uploads\/2017\/07\/blog1.jpg\" alt=\"blog1\" width=\"468\" height=\"605\" class=\"alignnone size-full wp-image-239\" \/><\/p>\n<p>The slow approach takes almost double the time, something that proves my fears about the &#8216;using&#8217; statement<\/p>\n<p>Increasing the RequestCount to 30 results in almost triple performance decrease:<\/p>\n<p><img loading=\"lazy\" src=\"https:\/\/www.dimlucas.com\/wp-content\/uploads\/2017\/07\/blog2.jpg\" alt=\"blog2\" width=\"372\" height=\"509\" class=\"alignnone size-full wp-image-240\" \/><\/p>\n<p>Increasing to 60 got me even closer to 3 times increase in performance improvement when using the fast approach.<\/p>\n<p>Imagine the performance increase that little modification can lead to in Microservices Oriented Applications.<\/p>\n<p>After digging around the internet for quite some time I stumbled upon an awesome article that describes the source of the issue. Apparently, it&#8217;s a TCP socket issue. <a href=\"https:\/\/aspnetmonsters.com\/2016\/08\/2016-08-27-httpclientwrong\/\">Check the article from ASP.NET Monsters for more information<\/a>.<\/p>\n<p>Oh and stop wrapping your HttpClients in &#8216;using&#8217; statements when making multiple requests. I certainly will.<\/p>\n<p>The whole project is available in this repo: <a href=\"https:\/\/github.com\/dimlucas\/HttpClientPerformanceTest\">https:\/\/github.com\/dimlucas\/HttpClientPerformanceTest<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The other day I was building a small demo ASP.NET Core 2.0 application for the purposes of a video course I&#8217;m preparing on the upcoming second version of .NET Core. The application was making several http requests to third party APIs. I noticed that it was taking unusually long to finish. At first I thought [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[57,127,122,126,123,125,124],"_links":{"self":[{"href":"https:\/\/www.dimlucas.com\/index.php\/wp-json\/wp\/v2\/posts\/238"}],"collection":[{"href":"https:\/\/www.dimlucas.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dimlucas.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dimlucas.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dimlucas.com\/index.php\/wp-json\/wp\/v2\/comments?post=238"}],"version-history":[{"count":3,"href":"https:\/\/www.dimlucas.com\/index.php\/wp-json\/wp\/v2\/posts\/238\/revisions"}],"predecessor-version":[{"id":313,"href":"https:\/\/www.dimlucas.com\/index.php\/wp-json\/wp\/v2\/posts\/238\/revisions\/313"}],"wp:attachment":[{"href":"https:\/\/www.dimlucas.com\/index.php\/wp-json\/wp\/v2\/media?parent=238"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dimlucas.com\/index.php\/wp-json\/wp\/v2\/categories?post=238"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dimlucas.com\/index.php\/wp-json\/wp\/v2\/tags?post=238"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}