Do HttpClient and HttpClientHandler have to be disposed?

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:

  • The original blog article announcing the relase of HttpClient.
  • The actual MSDN documentation for HttpClient.
  • BingTranslateSample
  • GoogleMapsSample
  • WorldBankSample
  • 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 superflous to this question, which is not concerned about how many times you can use an HttpClient instance, but if it 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?


  • 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.


    In my understanding, calling Dispose() is necessary only when it's locking resources you need later (like a particular connection). It's always recommended to free resources you're no longer using, even if you don't need them again, simply because you shouldn't generally be holding onto resources you're not using (pun intended).

    The Microsoft example is not incorrect, necessarily. All resources used will be released when the application exits. And in the case of that example, that happens almost immediately after the HttpClient is done being used. In like cases, explicitly calling Dispose() is somewhat superfluous.

    But, in general, when a class implements IDisposable , the understanding is that you should Dispose() of its instances as soon as you're fully ready and able. I'd posit this is particularly true in cases like HttpClient wherein it's not explicitly documented as to whether resources or connections are being held onto/open. In the case wherein the connection will be reused again [soon], you'll want to forgo Dipose() ing of it -- you're not "fully ready" in that case.

    See also: IDisposable.Dispose Method and When to call Dispose


    The current answers are a bit confusing and misleading, and they are missing some important DNS implications. I'll try to summarize where things stand clearly.

  • Generally speaking most IDisposable objects should ideally be disposed when you are done with them , especially those that own Named/shared OS resources. HttpClient is no exception, since as Darrel Miller points out it allocates cancellation tokens, and request/response bodies can be unmanaged streams.
  • However, the best practice for HttpClient says you should create one instance and reuse it as much as possible (using its thread-safe members in multi-threaded scenarios). Therefore, in most scenarios you'll never dispose of it simply because you will be needing it all the time .
  • The problem with re-using the same HttpClient "forever" is that the underlying HTTP connection might remain open against the originally DNS-resolved IP, regardless of DNS changes. This can be an issue in scenarios like blue/green deployment and DNS-based failover . There are various approaches for dealing with this issue, the most reliable one involving the server sending out a Connection:close header after DNS changes take place. Another possibility involves recycling the HttpClient on the client side, either periodically or via some mechanism that learns about the DNS change. See https://github.com/dotnet/corefx/issues/11224 for more information (I suggest reading it carefully before blindly using the code suggested in the linked blog post).
  • 链接地址: http://www.djcxy.com/p/54040.html

    上一篇: 将方法标记为安全

    下一篇: HttpClient和HttpClientHandler必须被丢弃吗?