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

rin*_*esh 8 asp.net dotnet-httpclient azure-functions .net-6.0

在我的 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>();
Run Code Online (Sandbox Code Playgroud)

并在 MyCustomService 构造函数中注入 MyCustomClient

private readonly IMyCustomClient _myCustomClient;

public PlatformEventManagementService(IMyCustomClient myCustomClient)
{
    _myCustomClient = myCustomClient;
}
Run Code Online (Sandbox Code Playgroud)

var result = await _myCustomClient.GetResponse();

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

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

Ton*_*onu 14

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

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

要解决此问题,应将工厂配置为为每个客户端创建一个新的处理程序。您可能希望使用 MS文档中显示的更简单的语法。

// 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;
    });
Run Code Online (Sandbox Code Playgroud)