You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 3.1中使用Typed HttpClient出现SocketsHttpHandler已释放异常求助

解决大量请求后出现 Cannot access a disposed object. Object name: 'SocketsHttpHandler' 的问题

首先,我注意到你的代码里有一个明显的异步操作错误,这大概率是触发该问题的核心原因:

在ClientService.GetInfo方法中,你错误地混合使用了await和.Result:

var stream = await _httpClient.GetAsync(uri).Result.Content.ReadAsStreamAsync();

这种写法会强制阻塞异步执行流程,破坏ASP.NET Core的异步上下文管理,在高并发场景下很容易导致底层资源(比如SocketsHttpHandler)被意外释放。

第一步:修复异步调用逻辑

去掉.Result,直接通过await获取异步操作结果,保持异步流程的一致性:

async public Task<Model> GetInfo(string id) {
    var uri = ServiceAPI.API.GetOperation(_remoteServiceBaseUrl, id);
    var response = await _httpClient.GetAsync(uri);
    // 建议添加响应状态检查,避免无效响应引发后续错误
    response.EnsureSuccessStatusCode();
    var stream = await response.Content.ReadAsStreamAsync();
    var cbor = CBORObject.Read(stream);
    return JsonConvert.DeserializeObject<ModelDTO>(cbor.ToJSONString());
}

第二步:检查客户端证书的生命周期

确保你注入的clientCertificate对象不会被提前回收。如果证书是从文件或内存流加载的,要保证它的引用在HttpClientHandler的生命周期内始终有效。比如加载证书时使用合适的存储标志,避免临时对象被GC回收:

// 示例:正确加载证书的方式
var cert = new X509Certificate2(
    "path/to/your/cert.pfx", 
    "cert-password", 
    X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet
);
// 建议将证书作为Singleton注入DI容器,确保其长期有效

第三步:确认HttpMessageHandler的池化配置

ASP.NET Core默认会对HttpMessageHandler进行池化管理(默认生命周期为2分钟),如果你的handler依赖了短期存在的对象,可能会在handler被池化回收后引发问题。你可以调整池化生命周期,或者根据需求修改池化策略:

services.AddHttpClient<IClientService, ClientService>(c => { })
    .SetHandlerLifetime(TimeSpan.FromMinutes(5)) // 调整handler的池化生命周期
    .ConfigurePrimaryHttpMessageHandler(() => {
        var handler = new HttpClientHandler();
        handler.ClientCertificateOptions = ClientCertificateOption.Manual;
        handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
        handler.ClientCertificates.Add(clientCertificate);
        handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
        return handler;
    });

第四步:禁止手动Dispose HttpClient

确保代码中没有手动调用_httpClient.Dispose(),Typed HttpClient的实例由DI容器负责管理,框架会处理其回收和池化逻辑,手动Dispose会直接导致底层的SocketsHttpHandler被提前释放。

额外提醒:生产环境不要跳过证书验证

你的代码中ServerCertificateCustomValidationCallback直接返回true,这会跳过服务器证书的合法性验证,仅建议在测试环境使用;生产环境请保留默认验证逻辑,或根据业务需求实现安全的自定义验证。

按照以上步骤调整后,高并发场景下的SocketsHttpHandler已释放错误应该能得到解决。

内容的提问来源于stack exchange,提问作者NEO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 10:53:00