假设我们有代码片段
builder.Services.AddHttpClient("typicode", c =>
{
c.BaseAddress = new Uri("https://xxx");
c.DefaultRequestHeaders.Add(
"accept", "application/json");
})
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler()
{
PooledConnectionLifetime = TimeSpan.FromMinutes(5),
})
.SetHandlerLifetime(TimeSpan.FromMinutes(10));
我不太明白为什么需要调用它SetHandlerLifetime(TimeSpan.FromMinutes(10)
,或者调用它有什么好处?我知道它控制着实例(及其连接池)在“处理程序级别”的重用SetHandlerLifetime
时长,以及在“连接级别”的重用时长。SocketsHttpHandler
PooledConnectionLifetime = TimeSpan.FromMinutes(5)
但使用还不够吗PooledConnectionLifetime = TimeSpan.FromMinutes(5)
,想象一下我使用这个 HttpClient 对不同的 url 进行多个请求,例如 foo1.com、foo2.com......foo10.com,我希望在连接级别上使用 5 分钟的 PooledConnectionIdleTimeout,例如 foo1.com 的连接在 5 分钟后过期,但 foo2.com 仍然处于活动状态并且我想稍后重新使用它,但是 SetHandlerLifetime 会在 10 分钟后清除所有池?
您不会使用它,因为如果您
SocketHttpHandler
在ConfigurePrimaryHttpMessageHandler
/上使用,它本质上是一个冗余的 APIUseSocketsHttpHandler
。这就是为什么微软建议不要同时配置这两个生命周期选项。结合使用 IHttpClientFactory 和 SocketsHttpHandler 的指南如下:
此外,在 .NET 9 中,HttpClientFactory 使用 SocketsHttpHandler 作为主要处理程序,并且
HandlerLifetime
API 实际上用于设置PooledConnectionLifetime
:但是,根据HttpClientFactory #101808 中的 Make SocketsHttpHandler 作为默认主处理程序,轮换/回收默认情况下不会被禁用(如上述文档片段中所建议):
因此,在 .NET 9 中(目前),两个生命周期值默认匹配,在我看来,你会得到一些重复的功能。更多关于默认禁用轮换/回收的讨论,请
SocketsHttpHandler
参阅IHttpClientFactory
“考虑更新 HttpClientFactory 默认值以利用 SocketsHttpHandler #35987”。附言:一些可能有用的调试代码
你已经知道这一点,但让我重申一下:
SetHandlerLifetime用于控制池中处理程序的生命周期
IHttpClientFactory
PooledConnectionLifetime用于控制处理程序池连接的生存期
处理程序会存储其访问的站点的 Cookie、证书和连接池,因此如果处理程序过期并被处置,其所有连接也将过期。处理程序的默认生命周期为 2 分钟,因此如果仅将其设置为
PooledConnectionLifetime
5 分钟则没有意义。随着访问的网站越来越多,处理程序占用的内存也会随之增加,这或许就是为什么处理程序会有一个默认的生命周期。所以,如果您不介意内存的增长,可以将生命周期设置为
InfiniteTimeSpan
。