[c#] Do HttpClient and HttpClientHandler have to be disposed between requests?

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:

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

  2. If it's not necessary, would it be a "good practice" anyway, since they implement IDisposable?

  3. If it's necessary (or recommended), is this code mentioned above implementing it safely (for .NET Framework 4.5)?

  4. If these classes don't require calling Dispose(), why were they implemented as IDisposable?

  5. If they require, or if it's a recommended practice, are the Microsoft examples misleading or unsafe?

This question is related to c# .net-4.5 idisposable using dotnet-httpclient

The answer is


Short answer: No, the statement in the currently accepted answer is NOT accurate: "The general consensus is that you do not (should not) need to dispose of HttpClient".

Long answer: BOTH of the following statements are true and achieveable at the same time:

  1. "HttpClient is intended to be instantiated once and re-used throughout the life of an application", quoted from official documentation.
  2. An IDisposable object is supposed/recommended to be disposed.

And they DO NOT NECESSARILY CONFLICT with each other. It is just a matter of how you organize your code to reuse an HttpClient AND still dispose it properly.

An even longer answer quoted from my another answer:

It is not a coincidence to see people in some blog posts blaming how HttpClient 's IDisposable interface makes them tend to use the using (var client = new HttpClient()) {...} pattern and then lead to exhausted socket handler problem.

I believe that comes down to an unspoken (mis?)conception: "an IDisposable object is expected to be short-lived".

HOWEVER, while it certainly looks like a short-lived thing when we write code in this style:

using (var foo = new SomeDisposableObject())
{
    ...
}

the official documentation on IDisposable never mentions IDisposable objects have to be short-lived. By definition, IDisposable is merely a mechanism to allow you to release unmanaged resources. Nothing more. In that sense, you are EXPECTED to eventually trigger the disposal, but it does not require you to do so in a short-lived fashion.

It is therefore your job to properly choose when to trigger the disposal, base on your real object's life cycle requirement. There is nothing stopping you from using an IDisposable in a long-lived way:

using System;
namespace HelloWorld
{
    class Hello
    {
        static void Main()
        {
            Console.WriteLine("Hello World!");

            using (var client = new HttpClient())
            {
                for (...) { ... }  // A really long loop

                // Or you may even somehow start a daemon here

            }

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
}

With this new understanding, now we revisit that blog post, we can clearly notice that the "fix" initializes HttpClient once but never dispose it, that is why we can see from its netstat output that, the connection remains at ESTABLISHED state which means it has NOT been properly closed. If it were closed, its state would be in TIME_WAIT instead. In practice, it is not a big deal to leak only one connection open after your entire program ends, and the blog poster still see a performance gain after the fix; but still, it is conceptually incorrect to blame IDisposable and choose to NOT dispose it.


In my case, I was creating an HttpClient inside a method that actually did the service call. Something like:

public void DoServiceCall() {
  var client = new HttpClient();
  await client.PostAsync();
}

In an Azure worker role, after repeatedly calling this method (without disposing the HttpClient), it would eventually fail with SocketException (connection attempt failed).

I made the HttpClient an instance variable (disposing it at the class level) and the issue went away. So I would say, yes, dispose the HttpClient, assuming its safe (you don't have outstanding async calls) to do so.


If you want to dispose of HttpClient, you can if you set it up as a resource pool. And at the end of your application, you dispose your resource pool.

Code:

// Notice that IDisposable is not implemented here!
public interface HttpClientHandle
{
    HttpRequestHeaders DefaultRequestHeaders { get; }
    Uri BaseAddress { get; set; }
    // ...
    // All the other methods from peeking at HttpClient
}

public class HttpClientHander : HttpClient, HttpClientHandle, IDisposable
{
    public static ConditionalWeakTable<Uri, HttpClientHander> _httpClientsPool;
    public static HashSet<Uri> _uris;

    static HttpClientHander()
    {
        _httpClientsPool = new ConditionalWeakTable<Uri, HttpClientHander>();
        _uris = new HashSet<Uri>();
        SetupGlobalPoolFinalizer();
    }

    private DateTime _delayFinalization = DateTime.MinValue;
    private bool _isDisposed = false;

    public static HttpClientHandle GetHttpClientHandle(Uri baseUrl)
    {
        HttpClientHander httpClient = _httpClientsPool.GetOrCreateValue(baseUrl);
        _uris.Add(baseUrl);
        httpClient._delayFinalization = DateTime.MinValue;
        httpClient.BaseAddress = baseUrl;

        return httpClient;
    }

    void IDisposable.Dispose()
    {
        _isDisposed = true;
        GC.SuppressFinalize(this);

        base.Dispose();
    }

    ~HttpClientHander()
    {
        if (_delayFinalization == DateTime.MinValue)
            _delayFinalization = DateTime.UtcNow;
        if (DateTime.UtcNow.Subtract(_delayFinalization) < base.Timeout)
            GC.ReRegisterForFinalize(this);
    }

    private static void SetupGlobalPoolFinalizer()
    {
        AppDomain.CurrentDomain.ProcessExit +=
            (sender, eventArgs) => { FinalizeGlobalPool(); };
    }

    private static void FinalizeGlobalPool()
    {
        foreach (var key in _uris)
        {
            HttpClientHander value = null;
            if (_httpClientsPool.TryGetValue(key, out value))
                try { value.Dispose(); } catch { }
        }

        _uris.Clear();
        _httpClientsPool = null;
    }
}

var handler = HttpClientHander.GetHttpClientHandle(new Uri("base url")).

  • HttpClient, as an interface, can't call Dispose().
  • Dispose() will be called in a delayed fashion by the Garbage Collector. Or when the program cleans up the object through its destructor.
  • Uses Weak References + delayed cleanup logic so it remains in use so long as it is being reused frequently.
  • It only allocates a new HttpClient for each base URL passed to it. Reasons explained by Ohad Schneider answer below. Bad behavior when changing base url.
  • HttpClientHandle allows for Mocking in tests

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


Please take a read on my answer to a very similar question posted below. It should be clear that you should treat HttpClient instances as singletons and re-used across requests.

What is the overhead of creating a new HttpClient per call in a WebAPI client?


Dispose() calls the code below, which closes the connections opened by the HttpClient instance. The code was created by decompiling with dotPeek.

HttpClientHandler.cs - Dispose

ServicePointManager.CloseConnectionGroups(this.connectionGroupName);

If you don't call dispose then ServicePointManager.MaxServicePointIdleTime, which runs by a timer, will close the http connections. The default is 100 seconds.

ServicePointManager.cs

internal static readonly TimerThread.Callback s_IdleServicePointTimeoutDelegate = new TimerThread.Callback(ServicePointManager.IdleServicePointTimeoutCallback);
private static volatile TimerThread.Queue s_ServicePointIdlingQueue = TimerThread.GetOrCreateQueue(100000);

private static void IdleServicePointTimeoutCallback(TimerThread.Timer timer, int timeNoticed, object context)
{
  ServicePoint servicePoint = (ServicePoint) context;
  if (Logging.On)
    Logging.PrintInfo(Logging.Web, SR.GetString("net_log_closed_idle", (object) "ServicePoint", (object) servicePoint.GetHashCode()));
  lock (ServicePointManager.s_ServicePointTable)
    ServicePointManager.s_ServicePointTable.Remove((object) servicePoint.LookupString);
  servicePoint.ReleaseAllConnectionGroups();
}

If you haven't set the idle time to infinite then it appears safe not to call dispose and let the idle connection timer kick-in and close the connections for you, although it would be better for you to call dispose in a using statement if you know you are done with an HttpClient instance and free up the resources faster.


I think one should use singleton pattern to avoid having to create instances of the HttpClient and closing it all the time. If you are using .Net 4.0 you could use a sample code as below. for more information on singleton pattern check here.

class HttpClientSingletonWrapper : HttpClient
{
    private static readonly Lazy<HttpClientSingletonWrapper> Lazy= new Lazy<HttpClientSingletonWrapper>(()=>new HttpClientSingletonWrapper()); 

    public static HttpClientSingletonWrapper Instance {get { return Lazy.Value; }}

    private HttpClientSingletonWrapper()
    {
    }
}

Use the code as below.

var client = HttpClientSingletonWrapper.Instance;

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.

  1. 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.
  2. 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.
  3. 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).

Since it doesn't appear that anyone has mentioned it here yet, the new best way to manage HttpClient and HttpClientHandler in .NET Core 2.1 is using HttpClientFactory.

It solves most of the aforementioned issues and gotchas in a clean and easy-to-use way. From Steve Gordon's great blog post:

Add the following packages to your .Net Core (2.1.1 or later) project:

Microsoft.AspNetCore.All
Microsoft.Extensions.Http

Add this to Startup.cs:

services.AddHttpClient();

Inject and use:

[Route("api/[controller]")]
public class ValuesController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;

    public ValuesController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    [HttpGet]
    public async Task<ActionResult> Get()
    {
        var client = _httpClientFactory.CreateClient();
        var result = await client.GetStringAsync("http://www.google.com");
        return Ok(result);
    }
}

Explore the series of posts in Steve's blog for lots more features.


Using dependency injection in your constructor makes managing the lifetime of your HttpClient easier - taking the lifetime managemant outside of the code that needs it and making it easily changable at a later date.

My current preference is to create a seperate http client class that inherits from HttpClient once per target endpoint domain and then make it a singleton using dependency injection. public class ExampleHttpClient : HttpClient { ... }

Then I take a constructor dependency on the custom http client in the service classes where I need access to that API. This solves the lifetime problem and has advantages when it comes to connection pooling.

You can see a worked example in related answer at https://stackoverflow.com/a/50238944/3140853


In typical usage (responses<2GB) it is not necessary to Dispose the HttpResponseMessages.

The return types of the HttpClient methods should be Disposed if their Stream Content is not fully Read. Otherwise there is no way for the CLR to know those Streams can be closed until they are garbage collected.

  • If you are reading the data into a byte[] (e.g. GetByteArrayAsync) or string, all data is read, so there is no need to dispose.
  • The other overloads will default to reading the Stream up to 2GB (HttpCompletionOption is ResponseContentRead, HttpClient.MaxResponseContentBufferSize default is 2GB)

If you set the HttpCompletionOption to ResponseHeadersRead or the response is larger than 2GB, you should clean up. This can be done by calling Dispose on the HttpResponseMessage or by calling Dispose/Close on the Stream obtained from the HttpResonseMessage Content or by reading the content completely.

Whether you call Dispose on the HttpClient depends on whether you want to cancel pending requests or not.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net-4.5

There is no argument given that corresponds to the required formal parameter - .NET Error The type or namespace name 'System' could not be found Which versions of SSL/TLS does System.Net.WebRequest support? async at console app in C#? Is it possible to run a .NET 4.5 app on XP? Awaiting multiple Tasks with different results Do you have to put Task.Run in a method to make it async? C# HttpClient 4.5 multipart/form-data upload Do HttpClient and HttpClientHandler have to be disposed between requests? What is the correct way to read a serial port using .NET framework?

Examples related to idisposable

Do HttpClient and HttpClientHandler have to be disposed between requests? Should I call Close() or Dispose() for stream objects? Should I Dispose() DataSet and DataTable? Use of Finalize/Dispose method in C# Proper use of the IDisposable interface When should I use GC.SuppressFinalize()?

Examples related to using

What is the use of "using namespace std"? Do HttpClient and HttpClientHandler have to be disposed between requests? MySQL JOIN ON vs USING? in a "using" block is a SqlConnection closed on return or exception? Should I Dispose() DataSet and DataTable? What is the best workaround for the WCF client `using` block issue? What is the C# Using block and why should I use it? What are the uses of "using" in C#?

Examples related to dotnet-httpclient

How do I pass an object to HttpClient.PostAsync and serialize as a JSON body? Custom header to HttpClient request Adding headers when using httpClient.GetAsync HttpClient - A task was cancelled? How to get content body from a httpclient call? Pass multiple complex objects to a post/put Web API method Deserialize JSON to Array or List with HTTPClient .ReadAsAsync using .NET 4.0 Task pattern Why is HttpClient BaseAddress not working? Make Https call using HttpClient Deciding between HttpClient and WebClient