System.Net.Http.HttpClient and System.Net.Http.HttpClientHandler in .NET Framework 4.5 implement IDisposable (via System.Net.Http.HttpMessageInvoker).
The using
statement documentation says:
As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement.
This answer uses this pattern:
var baseAddress = new Uri("http://example.com"); var cookieContainer = new CookieContainer(); using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer }) using (var client = new HttpClient(handler) { BaseAddress = baseAddress }) { var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("foo", "bar"), new KeyValuePair<string, string>("baz", "bazinga"), }); cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value")); var result = client.PostAsync("/test", content).Result; result.EnsureSuccessStatusCode(); }
But the most visible examples from Microsoft don't call Dispose()
either explicitly or implicitly. For instance:
In the announcement's comments, someone asked the Microsoft employee:
After checking your samples, I saw that you didn't perform the dispose action on HttpClient instance. I have used all instances of HttpClient with using statement on my app and I thought that it is the right way since HttpClient implements the IDisposable interface. Am I on the right path?
His answer was:
In general that is correct although you have to be careful with "using" and async as they dont' really mix in .Net 4, In .Net 4.5 you can use "await" inside a "using" statement.
Btw, you can reuse the same HttpClient as many times are [as] you like so typically you won't create/dispose them all the time.
The second paragraph is superfluous to this question, which is not concerned about how many times you can use an HttpClient instance, but about if it is necessary to dispose it after you no longer need it.
(Update: in fact that second paragraph is the key to the answer, as provided below by @DPeden.)
So my questions are:
Is it necessary, given the current implementation (.NET Framework 4.5), to call Dispose() on HttpClient and HttpClientHandler instances? Clarification: by "necessary" I mean if there are any negative consequences for not disposing, such as resource leakage or data corruption risks.
If it's not necessary, would it be a "good practice" anyway, since they implement IDisposable?
If it's necessary (or recommended), is this code mentioned above implementing it safely (for .NET Framework 4.5)?
If these classes don't require calling Dispose(), why were they implemented as IDisposable?
If they require, or if it's a recommended practice, are the Microsoft examples misleading or unsafe?
It will by create a new HttpClientHandler instance for the HttpClient to use and pass that into the next constructor which in turn means that the disposeHandler value will be true here too. To recap; all but the most parameter-rich constructor will be set up to dispose of the HttpMessageHandler.
The HttpClient instances injected by DI, can be disposed of safely, because the associated HttpMessageHandler is managed by the factory. As a matter of fact, injected HttpClient instances are Scoped from a DI perspective.
You do NOT need to reuse SqlConnection, because it will handle its connection pool better that way. The difference is caused by their implementation approach. Each HttpClient instance uses its own connection pool (quoted from here); but SqlConnection itself is managed by a central connection pool, according to this.
The safest, general advice would be to always dispose of the HttpResponseMessage once you have finished with using it. This does lead to a little more code noise but ensures that regardless of the internals and any future changes, your code will free/clean up unused resources such as connections as quickly as possible.
The general consensus is that you do not (should not) need to dispose of HttpClient.
Many people who are intimately involved in the way it works have stated this.
See Darrel Miller's blog post and a related SO post: HttpClient crawling results in memory leak for reference.
I'd also strongly suggest that you read the HttpClient chapter from Designing Evolvable Web APIs with ASP.NET for context on what is going on under the hood, particularly the "Lifecycle" section quoted here:
Although HttpClient does indirectly implement the IDisposable interface, the standard usage of HttpClient is not to dispose of it after every request. The HttpClient object is intended to live for as long as your application needs to make HTTP requests. Having an object exist across multiple requests enables a place for setting DefaultRequestHeaders and prevents you from having to re-specify things like CredentialCache and CookieContainer on every request as was necessary with HttpWebRequest.
Or even open up DotPeek.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With