讲师中心 微信公众号
AI工具推荐 视频效率加速

C# HttpClientFactory使用方法 C#如何正确管理HttpClient实例

落磊小哥_5979

落磊小哥_5979

发布时间:2026-01-30 11:35:20

|

159人浏览过

|

来源于php中文网

原创

应长期复用 HttpClient 而非每次 new,因其线程安全且内部 HttpMessageHandler 持有连接池与 DNS 缓存;频繁创建会导致端口耗尽、连接复用失败和 Socket 资源泄漏。

c# httpclientfactory使用方法 c#如何正确管理httpclient实例

为什么不能每次 new HttpClient()?

直接 new HttpClient() 会导致端口耗尽、DNS 缓存失效、连接复用失败等问题。.NET 的 HttpClient 是线程安全且设计为长期复用的,频繁创建销毁会触发底层 Socket 资源泄漏(尤其在高并发下),错误日志里常出现 SocketException: An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full。

根本原因不是 HttpClient 本身没 Dispose,而是它内部的 HttpMessageHandler(默认是 HttpClientHandler)持有连接池和 DNS 缓存,过早释放会打断复用链路。

HttpClientFactory 是怎么解决这个问题的?

HttpClientFactory 不是帮你“创建 HttpClient”,而是管理背后的 HttpMessageHandler 生命周期,并按需提供轻量级、短命的 HttpClient 实例(每个实例只持有一个 handler 引用,不拥有 handler)。handler 由工厂统一维护,默认 2 分钟空闲后回收,支持 DNS 刷新、连接池自动调优。

使用时你拿到的是“借用”的 HttpClient,不用 Dispose,也不该缓存它——下次 GetClient("api") 拿到的可能是新实例,但底层 handler 很可能复用。

关键点:

  • AddHttpClient 注册时传入的配置(如 BaseAddress、Timeout、DefaultRequestHeaders)只影响新生成的 client 实例,不影响 handler
  • handler 级别配置(如 MaxConnectionsPerServer)必须通过 ConfigurePrimaryHttpMessageHandler 或自定义 IHttpMessageHandlerBuilderFilter 设置
  • 命名客户端(如 services.AddHttpClient("github", c => c.BaseAddress = new Uri("https://api.github.com/")))适合多服务场景,类型化客户端更利于单元测试

类型化客户端(Typed Client)怎么写才对?

类型化客户端本质是一个普通类,构造函数接收 IHttpClientFactory 或直接注入 HttpClient(推荐后者,更简洁)。它不是单例,每次解析都新建,但内部的 HttpClient 由工厂供应,生命周期解耦。

示例:

GitHub操作助手
GitHub操作助手

用大白话操作当前项目的 Git/GitHub——配置 GitHub(装 gh CLI + 登录 + 建仓库)、备份、拉取下载、查询历史、回滚代码、管理分支。当用户用日常语言表达 git 意图时触发(例如"git备份一下""git下载项目""git拉下来""git看看我改了啥""git回退到上一个版本""git新建个分支搞新功能""git合并到主分支""git

下载
public class GitHubService
{
    private readonly HttpClient _httpClient;

    public GitHubService(HttpClient httpClient)
    {
        _httpClient = httpClient;
        _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("myapp/1.0");
    }

    public async Task<string> GetLatestRelease(string repo)
    {
        var response = await _httpClient.GetAsync($"/repos/{repo}/releases/latest");
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync();
    }
}

注册方式:

services.AddHttpClient<GitHubService>(client =>
{
    client.BaseAddress = new Uri("https://api.github.com/");
    client.Timeout = TimeSpan.FromSeconds(10);
});

注意:AddHttpClient<t></t> 注册的是服务类型,不是 HttpClient;T 构造函数中注入的 HttpClient 已被工厂包装,无需再处理重试或超时逻辑(这些应放在 factory 配置或 Polly 策略里)。

超时、重试、认证这些怎么加?

超时建议设在 HttpClient 实例级别(通过 AddHttpClient 配置),而不是在每次请求时用 CancellationToken 控制——后者只中断当前请求,不释放连接;前者能触发 handler 层连接清理。

重试和断路器必须用 IHttpClientBuilder.AddPolicyHandler(基于 Polly),例如:

services.AddHttpClient<GitHubService>()
    .SetHandlerLifetime(TimeSpan.FromMinutes(5))
    .AddPolicyHandler(Policy.Handle<HttpRequestException>()
        .OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
        .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))));

认证头推荐用 AddHttpMessageHandler 注入自定义 DelegatingHandler,避免每次手动设置 DefaultRequestHeaders:

  • Token 过期需刷新?不要在 handler 里同步调用 GetAccessTokenAsync,改用 IAsyncAuthorizationHeaderProvider 模式或配合 ITokenProvider + RefreshTokenHandler
  • Basic Auth 明文密码?把凭据存在 IConfiguration 或 ISecretsManager,handler 中读取后编码
  • Bearer Token 需动态更新?handler 中检查 DateTimeOffset.Now ,过期则异步刷新并更新 <code>Authorization 头

handler 的 SendAsync 是同步入口,所有 await 必须显式声明,否则会阻塞连接池线程。

热门AI工具

更多
SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

相关专题

更多
登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

14966

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

1745

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

4177

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

6341

2024.03.01

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

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

4658

2023.08.10

github中文官网入口 github中文版官网网页进入
github中文官网入口 github中文版官网网页进入

github中文官网入口https://docs.github.com/zh/get-started,GitHub 是一种基于云的平台,可在其中存储、共享并与他人一起编写代码。 通过将代码存储在GitHub 上的“存储库”中,你可以: “展示或共享”你的工作。 持续“跟踪和管理”对代码的更改。

8765

2026.01.21

GitHub官网入口版本汇总
GitHub官网入口版本汇总

本专题整合了GitHub入口版本地址汇总,阅读专题下面的文章了解更多详细内容。

938

2026.04.02

http与https有哪些区别
http与https有哪些区别

http与https的区别:1、协议安全性;2、连接方式;3、证书管理;4、连接状态;5、端口号;6、资源消耗;7、兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

5530

2024.08.16

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

20

2026.11.05

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Postman Native Git工作流指南
Postman Native Git工作流指南

共0课时 | 0人学习

vscode手册
vscode手册

共0课时 | 0人学习

Git 教程
Git 教程

共21课时 | 8.2万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn