gpt4 book ai didi

c# - 我应该缓存并重用从 HttpClientFactory 创建的 HttpClient 吗?

转载 作者:太空狗 更新时间:2023-10-29 20:12:25 26 4
gpt4 key购买 nike

我们可以在这里阅读YOU'RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE我们不应该为每个 http 请求创建和处理 HttpClient。相反,它应该被缓存和重用(例如作为 DI 容器中的 Singleton)。以及 HttpClient 的官方 .NET 文档中:

HttpClient 旨在实例化一次并在应用程序的整个生命周期中重复使用。为每个请求实例化一个 HttpClient 类将耗尽重负载下可用的套接字数量。这将导致 SocketException 错误。下面是一个正确使用HttpClient的例子。

推荐使用HttpClientFactory,但是看了之后:

  public interface IHttpClientFactory
{
/// <summary>
/// Creates and configures an <see cref="T:System.Net.Http.HttpClient" /> instance using the configuration that corresponds
/// to the logical name specified by <paramref name="name" />.
/// </summary>
/// <param name="name">The logical name of the client to create.</param>
/// <returns>A new <see cref="T:System.Net.Http.HttpClient" /> instance.</returns>
/// <remarks>
/// <para>
/// Each call to <see cref="M:System.Net.Http.IHttpClientFactory.CreateClient(System.String)" /> is guaranteed to return a new <see cref="T:System.Net.Http.HttpClient" />
/// instance. Callers may cache the returned <see cref="T:System.Net.Http.HttpClient" /> instance indefinitely or surround
/// its use in a <langword>using</langword> block to dispose it when desired.
/// </para>
/// <para>
/// The default <see cref="T:System.Net.Http.IHttpClientFactory" /> implementation may cache the underlying
/// <see cref="T:System.Net.Http.HttpMessageHandler" /> instances to improve performance.
/// </para>
/// <para>
/// Callers are also free to mutate the returned <see cref="T:System.Net.Http.HttpClient" /> instance's public properties
/// as desired.
/// </para>
/// </remarks>
HttpClient CreateClient(string name);
}

它说每次调用都会创建一个 HttpClient 实例,调用者可以缓存它。

每次调用 IHttpClientFactory.CreateClient 都保证返回一个新的 HttpClient实例。调用者可以无限期地缓存返回的实例或环绕它在 using block 中使用以在需要时处理它。

所以问题是我应该完全依赖 HttpClientFactory 还是应该缓存从中创建的 HttpClient

在我们的项目中,我们每次请求时都使用HttpClientFactory.CreateClient,他仍然会出现套接字异常。

最佳答案

HttpClient 只是IDisposable 因为它的HttpMessageHandlerIDisposable。实际上,应该是长期存在的 HttpMessageHandler

HttpClientFactory 通过在内部保留一个长生命周期的 HttpMessageHandler 来工作。每当您请求 HttpClient 时,它都会使用长期存在的 HttpMessageHander,并告诉 HttpClient not 处理当 HttpClient 被释放时。

你可以看到on GitHub :

public HttpClient CreateClient(string name)
{
// ...

// Get a cached HttpMessageHandler
var handler = CreateHandler(name);

// Give it to a new HttpClient, and tell it not to dispose it
var client = new HttpClient(handler, disposeHandler: false);

// ...

return client;
}

因此,从技术上讲,无论是缓存 HttpClient 还是立即处置它都没有关系 - 处置它不会做任何事情(因为它被告知不要处置它的 HttpClientHandler,因为它由 HttpClientFactory 管理。

关于处理 HttpClientMSDN says :

Disposal of the client isn't required. Disposal cancels outgoing requests and guarantees the given HttpClient instance can't be used after calling Dispose. IHttpClientFactory tracks and disposes resources used by HttpClient instances. The HttpClient instances can generally be treated as .NET objects not requiring disposal.

Keeping a single HttpClient instance alive for a long duration is a common pattern used before the inception of IHttpClientFactory. This pattern becomes unnecessary after migrating to IHttpClientFactory.

我怀疑您看到的 SocketException 有不同的原因。也许提出一个针对他们的新问题?

关于c# - 我应该缓存并重用从 HttpClientFactory 创建的 HttpClient 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54597303/

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