gpt4 book ai didi

c# - 来自 IHttpClientFactory 的类型化 HttpClient 实例的生命周期是多长,其中将接收它的类型注册为 "AddScoped"?

转载 作者:行者123 更新时间:2023-12-05 03:19:23 27 4
gpt4 key购买 nike

长话短说

在 .NET 6 中:

类型化的生命周期是多少 HttpClient来自 IHttpClientFactory 的实例将接收它的类型在哪里注册为“Scoped”?

当我们像下面的摘录那样注册它时,它不应该是一种“定时单例”(不管将使用它的类的生命周期如何)吗?或者是 HttpClient Transient - .NET 不缓存其任何配置,只有 Handler 被池化?

services.AddHttpClient<IServiceInterface, ServiceImpl>(client =>
{
client.BaseAddress = "<some absolute URL here>";
}
.SetHandlerLifetime(TimeSpan.FromMinutes(5));

services.AddScoped<IServiceInterface, ServiceImpl>();

上下文

我正在处理的应用程序访问位于不同地址的多个外部 API。我已经将每个服务访问逻辑封装到具有各自接口(interface)的服务类中,因此它们可以在运行时注入(inject)。按照 Microsoft 的规定,I'm using Typed HttpClients ,我写了一个辅助方法来配置它们在 Startup.cs :

public static IServiceCollection ConfigureHttpClientForService<TInterface, TImpl>
(this IServiceCollection services, Func<IServiceProvider, Uri> func)
where TInterface : class
where TImpl : class, TInterface
{
services.AddHttpClient<TInterface, TImpl>((provider, client) =>
{
var uri = func(provider);
client.BaseAddress = uri;
})
// Polly Rules here and other stuff
.SetHandlerLifetime(TimeSpan.FromMinutes(5));

return services;
}

然后,在 Startup.csConfigureServices我这样调用它的方法:

services
.ConfigureHttpClientForService<IServiceInterface, ServiceImpl>(provider =>
{
if (!Uri.TryCreate(
settings.UrlObjConfig.Url,
UriKind.RelativeOrAbsolute,
out var uri))
{
throw new UriFormatException("Invalid URL");
}

return uri;
});

在运行时,我注意到 Action<HttpClient>配置 HttpClient ( AddHttpClient<TClient,TImplementation>(IServiceCollection, Action<HttpClient>) - docs ) 当我从使用类型化客户端的服务调用方法时,每次都会被调用 - 换句话说,每次实例化 Scoped 服务时,都会运行该 Action。

问题

  1. 类型化的生命周期是多少HttpClient来自 IHttpClientFactory 的实例将接收它的类型在哪里注册为“AddScoped”?
  2. 这种行为是否正确? HttpClient 配置(例如基地址)是否应该以某种方式缓存或保存在某处,因为它是键入的?
  3. 如果我们有更极端的情况,是否会产生一些 GC 压力(为同一类型创建大量客户端)?

最佳答案

What is the lifetime of a typed HttpClient instance from IHttpClientFactory where the type that will receive it is registered as "AddScoped"?

如果你查看相关的源代码,那么你可以看到

Is this behaviour correct? Shouldn't the HttpClient configuration (e.g. Base Address) be cached somehow or saved somewhere, since it is typed?

AddHttpClient不提供显式接口(interface)来设置 BaseAddress .相反,它允许 API 的使用者指定一种方法 ( Action<HttpClient> configureClient ) 来配置 HttpClient如他所愿。

因此,BaseAddress没有被缓存。 HttpClient的生命周期也短,但是底层HttpClientMessageHandlerpooled . ( related source code )

管理底层 HttpClientMessageHandler 实例的池和生命周期。自动管理避免了手动管理 HttpClient 生命周期时出现的常见 DNS(域名系统)问题

旁注:有一个 cache inside DefaultTypedHttpClientFactory 这有助于创建类型化的 http 客户端。

Wouldn't it create some GC pressure (lots of clients being created for the same type) if we would have a more extreme scenario?

正如上面所讨论的,您输入的客户和 HttpClient来来去去。底层HttpMessageHandler s 被合并。

您很可能会首先达到传出并发调用的限制,而不是对 GC 造成太大压力。但是通过一些压力测试,您可以确定哪个问题最先出现。

还有一个cleanup process which runs every 10 seconds默认情况下。

关于c# - 来自 IHttpClientFactory 的类型化 HttpClient 实例的生命周期是多长,其中将接收它的类型注册为 "AddScoped"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73464868/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com