添加类型化HttpClient后程序陷入无限循环致内存耗尽问题排查
类型化HttpClient导致无限循环的原因与解决方法
核心问题:循环依赖
你的代码出现无限循环的根本原因是依赖注入循环引用:
当你调用AddHttpMessageHandler<AuthenticationDelegatingHandler>()为类型化HttpClient添加委托处理器时,若AuthenticationDelegatingHandler的构造函数中直接或间接注入了IHandler(或HandlerImplementation),就会触发以下循环链:
- 容器尝试创建
HandlerImplementation,需要先初始化对应的HttpClient实例 - 创建
HttpClient时,必须先实例化AuthenticationDelegatingHandler - 实例化
AuthenticationDelegatingHandler又需要IHandler,容器再次尝试创建HandlerImplementation,往复循环直至内存耗尽
解决方法
1. 移除委托处理器的循环依赖
检查AuthenticationDelegatingHandler的构造函数,移除对IHandler或HandlerImplementation的依赖。委托处理器的职责应仅聚焦于HTTP请求的认证逻辑,无需依赖调用它的业务Handler。
2. 延迟解析依赖
若确实需要在委托处理器中使用其他服务,改用IServiceProvider延迟获取,避免在构造阶段触发循环:
public class AuthenticationDelegatingHandler : DelegatingHandler { private readonly IServiceProvider _serviceProvider; public AuthenticationDelegatingHandler(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { using var scope = _serviceProvider.CreateScope(); var requiredService = scope.ServiceProvider.GetRequiredService<ISomeService>(); // 执行认证逻辑,比如添加请求头 request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", requiredService.GetToken()); return await base.SendAsync(request, cancellationToken); } }
3. 调整委托处理器的注册方式
先单独注册AuthenticationDelegatingHandler,再通过服务提供工厂获取,避免直接注入引发的循环:
// 先注册委托处理器 services.AddTransient<AuthenticationDelegatingHandler>(); // 配置类型化HttpClient时,通过工厂方法获取处理器 services.AddHttpClient<IHandler, HandlerImplementation>(opt => { opt.BaseAddress = new Uri(configuration.GetSection("endpoints")["remoteService"] ?? string.Empty); }).AddHttpMessageHandler(sp => sp.GetRequiredService<AuthenticationDelegatingHandler>());
内容的提问来源于stack exchange,提问作者Strike08
相关产品推荐
相关产品推荐

