Hello,
While upgrading our Web application from .NET Core 2.0.9 to 2.1.4, we started to see some ObjectDisposedException
popping up (roughly 30 mins after application start), stating that SocketsHttpHandler
could no longer be used.
Googling a bit led us to dotnet/runtime#27327. As this was supposed to fixed in 2.1.5, we decided to wait for it to be released.
Now, running on 2.1.5 we're still experiencing them.
I've trimmed down the project as much as I could into the simplest possible repro case I could come up with.
Steps:
System.ObjectDisposedException
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'SocketsHttpHandler'.
at System.Net.Http.SocketsHttpHandler.CheckDisposed()
at System.Net.Http.SocketsHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Web.Controllers.HomeController.InvokeSearch() in C:\REDACTED\src\Backend\Controllers\HomeController.cs:line 46
at Web.Controllers.HomeController.SearchAsync() in C:\REDACTED\src\Backend\Controllers\HomeController.cs:line 23
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at System.Threading.Tasks.ValueTask`1.get_Result()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
Repro project: Repro.zip
@geoffkizer
@karelz @davidsh @geoffkizer Is there anything I could do on my side to help move this issue forward?
We rollbacked on top of 2.0.x and running against a no longer supported version makes us... well... uncomfortable :wink:
@nulltoken we didn't get to it yet, sorry (a bit busy with other investigations for last few weeks :().
I hope we will have time to take a look next week.
Which OS does it happen on? Windows or Linux?
I assume you tried to repro it outside of ASP.NET, but failed, right?
I did a check...the issue is on you Startup
setup. You do this
```c#
ProxyAwareHttpClientHandler handler = new ProxyAwareHttpClientHandler(proxy);
services
.AddHttpClient(Options.DefaultName)
.ConfigurePrimaryHttpMessageHandler(() =>
{
return handler;
});
But [guide says](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.httpclientbuilderextensions.configureprimaryhttpmessagehandler?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DEN-US%26k%3Dk(Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.ConfigurePrimaryHttpMessageHandler);k(SolutionItemsProject);k(DevLang-csharp)%26rd%3Dtrue&view=aspnetcore-2.1) `The delegate should return a new instance of the message handler each time it is invoked.`
`ProxyAwareHttpClientHandler` is disposed after some time but you return "same" disposed instance...I think you need to do something like
```c#
Uri proxy = Configuration.GetValue<Uri>("http_proxy");
services
.AddHttpClient(Options.DefaultName)
.ConfigurePrimaryHttpMessageHandler(() =>
{
return new ProxyAwareHttpClientHandler(proxy);
});
With this fix it works on your repro.
@MarcoRossignoli HUGE thanks for helping us here with the investigation! Really appreciate it!
Seems to be answered, so closing. If there is reason to reopen, just let us know. Thanks!
@MarcoRossignoli Thanks for the help and the pointer to the documentation.
I'm going to test that and report here the outcome.
@MarcoRossignoli The outcome is .... wonderful. Thanks a lot! :heart:
Thank's for clear and complete repro...essential
Most helpful comment
I did a check...the issue is on you
Startup
setup. You do this```c#
ProxyAwareHttpClientHandler handler = new ProxyAwareHttpClientHandler(proxy);
services
.AddHttpClient(Options.DefaultName)
.ConfigurePrimaryHttpMessageHandler(() =>
{
return handler;
});
With this fix it works on your repro.