我应该缓存和重用从HttpClientFactory创建的HttpClient吗?

编程入门 行业动态 更新时间:2024-10-11 21:28:39
本文介绍了我应该缓存和重用从HttpClientFactory创建的HttpClient吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我们可以在此处阅读您正在使用HTTPCLIENT错误,这正在破坏您的身份软件,我们不应为每个http请求创建和处理HttpClient。相反,应该对其进行缓存和重用(例如,作为DI容器中的Singleton)。在 HttpClient :

We can read here YOU'RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE that we should not create and dispose HttpClient for each http request. Instead, it should be cached and reused (e.g as Singleton in DI container). As well in official .NET documentation for HttpClient:

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

HttpClient is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors. Below is an example using HttpClient correctly.

建议使用HttpClientFactory,但请注意以下内容:

The recommendation is to use HttpClientFactory, but after looking at:

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实例,调用者可以对其进行缓存

it says that each call will always create a HttpClient instance and caller may cache it.

每次对IHttpClientFactory.CreateClient的调用都保证返回一个新的HttpClient 实例。调用者可以无限期缓存返回的实例,也可以在需要时将其使用的包围在using块中以将其处置。

Each call to IHttpClientFactory.CreateClient is guaranteed to return a new HttpClient instance. Callers may cache the returned instance indefinitely or surround its use in a using block to dispose it when desired.

我应该完全依靠 HttpClientFactory 还是应该缓存从中创建的 HttpClient ?

So question is should I completely rely on HttpClientFactory or I should still cache created HttpClient from it?

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

In our project we use HttpClientFactory.CreateClient every time we make request and he will still having socket exceptions.

推荐答案

HttpClient 只能 IDisposable ,因为其 HttpMessageHandler 是 IDisposable 。实际上,它应该是长期保存的 HttpMessageHandler 。

HttpClient is only IDisposable because its HttpMessageHandler is IDisposable. In reality, it's the HttpMessageHandler which should be long-lived.

HttpClientFactory 通过在内部保留一个长期存在的 HttpMessageHandler 来工作。每当您请求 HttpClient 时,它都会使用寿命长的 HttpMessageHander ,并告诉 HttpClient 不处置 HttpClient 时将其丢弃。

HttpClientFactory works by keeping a long-lived HttpMessageHandler internally. Whenever you ask for a HttpClient, it uses the long-lived HttpMessageHander, and tells the HttpClient not to dispose it when the HttpClient is disposed.

您可以在GitHub上看到 :

You can see that 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 )。

So, technically it doesn't matter whether you cache the HttpClient or dispose it straight away - disposing it doesn't do anything (because it's been told not to dispose its HttpClientHandler, as that's managed by the HttpClientFactory).

关于处理 HttpClient , MSDN说:

不需要处置客户端。 Disposal取消传出的请求,并确保在调用Dispose之后不能使用给定的HttpClient实例。 IHttpClientFactory跟踪并处置HttpClient实例使用的资源。通常,可以将HttpClient实例视为不需要处理的.NET对象。

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.

使单个HttpClient实例长期存活是一种常见的模式,它始于IHttpClientFactory的诞生。 。迁移到IHttpClientFactory之后,不再需要这种模式。

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 s您发现原因有所不同。也许问一个针对他们的新问题?

I suspect the SocketExceptions you're seeing have a different cause. Perhaps ask a new question focussed on them?

更多推荐

我应该缓存和重用从HttpClientFactory创建的HttpClient吗?

本文发布于:2023-06-03 23:42:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/484983.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:缓存   HttpClientFactory   HttpClient

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!