es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obteniendo la excepción Cannot access a disposed object. Nombre del objeto: ‘SocketsHttpHandler’ en la aplicación .Net 6.

En una de mis aplicaciones de Azure Function (.Net 6 proceso aislado) estoy realizando algunas solicitudes http con un certificado de cliente. Estoy registrando mis servicios en el Program.cs de la siguiente manera,

var handler = new HttpClientHandler();
handler.ClientCertificates.Add(clientCertificate);

services.AddHttpClient().Configure<httpclientfactoryoptions>(
               "myClient", options =>
                   options.HttpMessageHandlerBuilderActions.Add(builder =>
                       builder.PrimaryHandler = handler));

services.AddTransient<imycustomclient, mycustomclient="">(provider =>
           new MyCustomClient(provider.GetService<ihttpclientfactory>(),
               cutomParameter1, cutomParameter2));

services.AddSingleton<imycustomservice, mycustomservice="">();

E inyectando MyCustomClient en el constructor de MyCustomService

private readonly IMyCustomClient _myCustomClient;

public PlatformEventManagementService(IMyCustomClient myCustomClient)
{
    _myCustomClient = myCustomClient;
}

var result = await _myCustomClient.GetResponse();

Funciona bien durante un tiempo y luego obtengo la siguiente excepción después de enviar muchas solicitudes.

No se puede acceder a un objeto desechado. Nombre del objeto: 'SocketsHttpHandler'.</imycustomservice,></imycustomclient,>

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La excepción “Cannot access a disposed object. Object name: ‘SocketsHttpHandler'” indica que el objeto SocketsHttpHandler utilizado por la instancia de HttpClient ha sido eliminado y no está disponible para su uso posterior.

    Para resolver este problema, puedes intentar agregar la sobrecarga AddHttpClient con una expresión lambda para configurar la instancia de HttpClientHandler y asegurarte de que el controlador no se elimine prematuramente. Además, puedes registrar la instancia de HttpClientHandler como un servicio singleton para asegurarte de que se reutilice en todas las instancias de HttpClient.

    Aquí tienes un ejemplo de código actualizado que implementa estas sugerencias:

    var handler = new HttpClientHandler();
    handler.ClientCertificates.Add(clientCertificate);
    
    services.AddSingleton<httpclienthandler>(handler);
    
    services.AddHttpClient("myClient", client =>
    {
        client.BaseAddress = new Uri("https://example.com/");
    })
    .ConfigurePrimaryHttpMessageHandler(() => services
        .GetService<httpclienthandler>().ConfigureRemoteCertificateValidation
        (delegate { return true; }));
    
    services.AddTransient<imycustomclient, mycustomclient="">(provider =>
        new MyCustomClient(provider.GetService<ihttpclientfactory>()
            .CreateClient("myClient"), customParameter1, customParameter2));
    
    services.AddSingleton<imycustomservice, mycustomservice="">();
    

    En el código actualizado, se registra la instancia de HttpClientHandler como un servicio singleton y las acciones HttpMessageHandlerBuilder se mueven a la sobrecarga AddHttpClient con la expresión lambda. La expresión lambda devuelve una nueva instancia de HttpClientHandler, lo que asegura que no se elimine prematuramente.

    Además, ten en cuenta que el delegado ConfigureRemoteCertificateValidation asegura que se omita la validación del certificado para el servidor remoto, lo que puede no ser seguro en todos los casos. Debes modificar este delegado según tus requisitos de seguridad.</imycustomservice,></imycustomclient,>

Comments are closed.