0

0

c# IHttpClientFactory 和 new HttpClient() 的区别

幻夢星雲

幻夢星雲

发布时间:2026-01-17 09:11:02

|

448人浏览过

|

来源于php中文网

原创

直接 new HttpClient() 在高并发下崩,因频繁创建导致 TIME_WAIT 端口耗尽、连接池与 DNS 缓存不复用、配置分散且易泄漏;IHttpClientFactory 通过共享 SocketsHttpHandler、统一配置、自动生命周期管理解决。

c# ihttpclientfactory 和 new httpclient() 的区别

直接 new HttpClient() 为什么会在高并发下崩?

不是它“不能用”,而是频繁 new HttpClient() 会快速耗尽本地端口TIME_WAIT 状态堆积),尤其在短生命周期服务(如 ASP.NET Core Controller 每次请求都 new 一个)中,几分钟内就可能触发 SocketException: Only one usage of each socket address is permitted。根本原因在于:HttpClient 虽轻量,但底层的 SocketsHttpHandler 是重量级资源——它持有连接池、SSL 会话缓存、DNS 解析结果。每次 new 都新建一套,既不复用,也不释放干净。

  • DNS 缓存不会刷新:比如你调用的 API 域名做了灰度切流,new HttpClient() 实例可能永远卡在旧 IP 上
  • 超时、Header、BaseAddress 等配置散落在各处,改一处漏十处
  • 没显式 Dispose()?.NET Core 会延迟回收,但连接池已泄漏;.NET Framework 下更严重,可能永久占用 socket

IHttpClientFactory 怎么解决这些问题?

IHttpClientFactory 不是“造 HttpClient 的工厂”,而是“管理连接池 + 注入策略 + 统一配置”的协调者。它背后只维护一组共享的 SocketsHttpHandler 实例,所有通过它创建的 HttpClient 都复用同一套底层连接池和 DNS 缓存策略(默认每 2 分钟刷新一次 DNS)。

  • 生命周期由 DI 容器托管:你注入 IHttpClientFactory,它活到应用结束;你调用 CreateClient("xxx") 得到的 HttpClient 是瞬态对象(可 Dispose,也可不 Dispose——工厂会自动清理)
  • 配置集中化:在 Program.cs 里统一设 BaseAddressTimeoutDefaultRequestHeaders
  • 天然支持弹性策略:比如集成 Polly,一行代码加重试:.AddPolicyHandler(Policy.Handle().WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(100)))

构造函数里该注入 IHttpClientFactory 还是 HttpClient?

必须注入 IHttpClientFactory,而不是直接注入 HttpClient。后者看似方便,实则是陷阱:

  • ASP.NET Core 会把 HttpClient 当作单例注册(如果你没配作用域),导致所有服务共享同一个实例 → 全局超时、Header 冲突、线程不安全(DefaultRequestHeaders 是共享集合)
  • 无法按业务区分配置:支付服务要 30 秒超时、通知服务只要 5 秒,单例 HttpClient 无法满足
  • 测试困难:你没法在单元测试中 mock 不同行为的客户端

正确姿势是:

企业黄页-大众投资指南整站 asp.net 2.0
企业黄页-大众投资指南整站 asp.net 2.0

大众投资指南是基于Asp.Net(2.0)+C#+Access(sql2000)的企业黄页类程序,是基于web2.0 模式的网站。 贴吧和黄页都有采集功能 主程序包括分类信息和商家黄页两大模块。分类信息支持二级分类,商家黄页支持二级地区分类及二级行业分类。程序采用了伪静态(url重写)技术,可选生成纯静态首页。 一、分类信息仿百度贴吧编写,可以分别对游客及会员设置不同的审核条件。会员发布信息

下载
public class PaymentService
{
    private readonly IHttpClientFactory _factory;
    public PaymentService(IHttpClientFactory factory) => _factory = factory;

    public async Task ProcessAsync()
    {
        var client = _factory.CreateClient("PaymentApiClient"); // 名称匹配注册时的 key
        await client.PostAsync("/charge", content);
    }
}

命名客户端 vs 类型化客户端,怎么选?

两者本质都是为了解耦配置与使用,区别在于绑定方式:

  • 命名客户端AddHttpClient("xxx")):灵活,适合多环境/多租户场景,比如 CreateClient("ProdApi")CreateClient("StagingApi") 指向不同地址
  • 类型化客户端AddHttpClient()):强类型,把客户端逻辑封装进类,构造函数直接接收配置好的 HttpClient,适合职责单一的服务(如专门调 GitHub API 的类)

注意:类型化客户端内部仍走工厂机制,不是 new 出来的;它的 HttpClient 参数由 DI 自动注入,生命周期受工厂管控——这点常被忽略。

真正容易被忽略的点是:即使用了 IHttpClientFactory,如果在非 DI 管理的类(比如静态工具类、BackgroundService 手动 new 的对象)里调用 CreateClient,依然可能因工厂未被正确释放或作用域错乱引发问题。工厂本身也依赖 DI 容器的生命周期管理,脱离上下文就失效。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

390

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

481

2023.08.10

SSL检测工具介绍
SSL检测工具介绍

SSL检测工具有SSL Labs、SSL Check、SSL Server Test、SSLMate、SSL/TLS Analyzer等。详细介绍:1、SSL Labs是一个由Qualys提供的在线SSL检测工具,可以评估服务器证书的部署情况、加密套件、协议支持等方面的安全性,它提供了一个详细的报告,包括证书的颁发者、有效期、安全性配置等;2、SSL Check等等。

329

2023.10.20

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

43

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

84

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

24

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

35

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

16

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.7万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号