uhaciogullari/HttpClientFactoryLite

Cannot access a disposed object after the HandlerLifetime

Closed this issue · 4 comments

Hi,

First of all, this library is great. It has a pure http only and no any dependencies which makes it good. We are encountering some issues when using this as a static and reusing it for our entire lifecycle of our application and web apps.

Using latest version from nuget, after the time has passed (depending on what you set in the Handlerlifetime), it will start giving Cannot access a disposed object when trying to access the same httpClient.

Here is the exception:

Cannot access a disposed object.
Object name: 'System.Net.Http.HttpClientHandler'. ---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Http.HttpClientHandler'.
at System.Net.Http.HttpClientHandler.CheckDisposed()
at System.Net.Http.HttpClientHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

We assume that the Factory auto disposed the httpClient and creates a new one so that it will refresh the DNS issue stuffs right?

We followed the instruction on how to use it, this is our code:

var httpClientFactory = new HttpClientFactory();

var httpClientHandler = new HttpClientHandler()
{
UseCookies = false
};

httpClientFactory.Register("test", builder => builder
.ConfigurePrimaryHttpMessageHandler(() => httpClientHandler)
.SetHandlerLifetime(TimeSpan.FromSeconds(30)));

then we make a singleton instance (static instance) of httpClientFactory, then we keep on reusing this method whenever we gonna make any rest api request:

var client = httpClientFactory.CreateClient("test");

var response = await client.SendAsync(request);

After sometime, the client.SendAsync will throw an exception: Cannot access a disposed object.

Please help.

@uhaciogullari We would like to ask for your help please.

Hello there

I'm on my phone right now but I can see that you are capturing a single handler instance in the delegate. Move the initialization inside the delegate and it should fix the problem.

Let me know when if it's nıt clear and I will share a code sample when I'm at my desk.

@uhaciogullari thanks man! I have tried to move the creation of new instance inside the ConfigurePrimaryHttpMessageHandler:

httpClientFactory.Register("test", builder => builder .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false; } ) .SetHandlerLifetime(TimeSpan.FromSeconds(30)));

And it works so far, the error is gone. We will try to observe this. Thanks for your help!

Am i right that the SetHandlerLifetime is the time before it refresh the DNS right (or keep the http client pooled) ?

And also, we don't need to dispose the httpClient right?

Also, do we need to tweak the new HttpClientHandler.MaxConnectionsPerServer = 99999 to use and maximize concurrent requests? We are heavily using several concurrent API requests and we want some best performance , any tips on how achieve it?

Thank you again.

Am i right that the SetHandlerLifetime is the time before it refresh the DNS right (or keep the http client pooled) ?

I think so

And also, we don't need to dispose the httpClient right?

No, you don't dispose it.

Also, do we need to tweak the new HttpClientHandler.MaxConnectionsPerServer = 99999 to use and maximize concurrent requests? We are heavily using several concurrent API requests and we want some best performance , any tips on how achieve it?

Not sure about this one. There could be a limit on OS level for this. I'm not an expert on the subject but I would suggest logging relevant information and monitoring the performance for a while.