无法访问已处置的对象。对象名称:.Net 6 应用程序中的 'SocketsHttpHandler' 异常

Getting Cannot access a disposed object. Object name: 'SocketsHttpHandler' exception in .Net 6 Application

在我的一个 Azure Function 应用程序(.Net 6 独立进程)中,我正在使用客户端证书发出一些 http 请求。我正在像这样在 Program.cs 中注册我的服务,

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>();

并在 MyCustomService 构造函数中注入 MyCustomClient

private readonly IMyCustomClient _myCustomClient;

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

var result = await _myCustomClient.GetResponse();

它在一段时间内工作正常,在发送许多请求后出现以下异常。

Cannot access a disposed object. Object name: 'SocketsHttpHandler'.

您正在为工厂提供 HttpClientHandler 的单个实例以供所有客户端使用。默认 HandlerLifetime 过去后(2 分钟),它将被标记为处置,实际处置发生在所有现有 HttpClient 引用它的处置之后。

在处理程序被标记后创建的所有客户端将继续提供即将被处置的处理程序,一旦处置被执行,它们将处于无效状态。

要解决此问题,应将工厂配置为为每个客户端创建一个新的处理程序。您可能希望使用 MS documentation.

中显示的更简单的语法
// Existing syntax
services.AddHttpClient().Configure<HttpClientFactoryOptions>(
                "myClient", options =>
                    options.HttpMessageHandlerBuilderActions.Add(builder =>
                    {
                        var handler = new HttpClientHandler();
                        handler.ClientCertificates.Add(clientCertificate);
                        builder.PrimaryHandler = handler;
                    }));

// MS extension method syntax
services
    .AddHttpClient("myClient")
    // Lambda could be static if clientCertificate can be retrieved from static scope
    .ConfigurePrimaryHttpMessageHandler(_ =>
    {
        var handler = new HttpClientHandler();
        handler.ClientCertificates.Add(clientCertificate);
        return handler;
    });