HttpClientFactory.Create 与新的 HttpClient
Posted
技术标签:
【中文标题】HttpClientFactory.Create 与新的 HttpClient【英文标题】:HttpClientFactory.Create vs new HttpClient 【发布时间】:2013-09-24 08:01:22 【问题描述】:我很好奇HttpClientFactory
class 的目的是什么。 MSDN 上没有说明它存在的原因(参见链接)。
Create
methods 有更专业的参数,但我主要想知道不带参数的调用和普通的构造函数有什么区别。
var httpClient = HttpClientFactory.Create();
VS
var httpClient = new HttpClient();
在大多数示例中,我看到new HttpClient()
的使用,没有任何using
语句,即使HttpClient
class 派生自IDisposable
。
由于HttpClient
类派生自IDisposable
,工厂是否进行了一些池化或缓存?是否有性能优势,还是无关紧要?
更新 – .NET Core 2.1 中的IHttpClientFactory
请注意,自从提出这个问题以来,已经发布了较新版本的 .NET,并且 .NET Core 2.1 引入了一种新的、经过大幅改进的方法来获取 HTTP 客户端。
关于使用 IHttpClientFactory
而不是 .NET Core,请参阅下面 Ali Bayat 的回答。
但是,我将 Darrel Miller 的答案保留为已接受的答案,因为这是在 .NET Framework v4.8 之前使用的正确答案,因此提出了这个问题。
在 .NET 5 中,.NET Framework 和 .NET Core 之间的差异将得到调整,您应该改用 IHttpClientFactory
。
【问题讨论】:
【参考方案1】:当管道中有多个 DelegatingHandler 时,工厂是帮助创建客户端的辅助方法。委托处理程序需要连接在一起以形成管道。该工厂允许您将处理程序作为数组传入,工厂将负责将它们连接在一起。
我相信,但不相信我的话,CreatePipeline 方法可以在服务器端用于为 Web API HttpServer 构建消息处理管道。
我很高兴您没有看到很多在 HTTPClient 周围使用块的示例,因为我多年来一直在与这种做法作斗争。尽管 HttpClient 确实实现了一次性,但它仅用于处理在请求进行时它被销毁的异常情况。 HttpClient 实例应该是长期存在的。处理它们会强制关闭应该被池化的底层 TCP 连接。 HttpClient 是线程安全的,可以被不同的线程安全地多次使用。这就是它的使用方式,而不是单次使用,使用我经常看到的块模式。
【讨论】:
感谢您的回复!在深入挖掘之后,我还遇到了this SO post,其中 David Faivre 解释了在重复更新太多HttpClient
s 时可能出现的问题。
@Darrel 所以如果我有一个长时间运行的 HttpClient 但最终我要摆脱它,那时我是否需要手动调用 dispose 或者我可以让它超出范围并且让 GC 处理它?
@Darrel,请注意,尽管大多数方法都是线程安全的,但实例成员却不是(大多数 .NET Framework 就是这种情况) - 请参阅 msdn.microsoft.com/en-us/library/…
如果没有命名的客户端(例如:对于不同的 baseUrls),httpCLientFactory.Create() 是否具有命名客户端的所有好处(不是说像 Polly 这样的自定义设置和功能)?【参考方案2】:
IHttpClientFactory
提供以下好处:
-
命名和配置逻辑
HttpClient
实例。
构建一个传出请求中间件来管理
关于 HTTP 请求的横切关注点。
与 Polly 集成以处理瞬态故障。
通过管理 HttpClient
生命周期来避免常见的 DNS 问题。
为通过由
工厂。
more
【讨论】:
感谢您添加此指南,因为在 .NET Core 中引入了IHttpClientFactory
,它是提出此问题时可用选项的更好替代方案。
我很好奇 .NET Core 中是否有一个实际的类实现了具体的 IHttpClientFactory?使用它的唯一方法似乎是使用 IoC 容器并调用 services.AddHttpClient()
IHttpClientFactory是DefaultHttpClientFactory实现的接口
@bytedev 到目前为止,似乎仍然没有一种方法可以在不依赖微软自己的 DI 容器的情况下使用具体实现。这里有关于这个问题的持续讨论:github.com/dotnet/aspnetcore/issues/28385
@AliBayat DefaultHttpClientFactory
是一个内部类,所以你不能从你自己的代码中实例化它。【参考方案3】:
如
中所述https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests#issues-with-the-original-httpclient-class-available-in-net-core
HttpClient
的默认构造函数
有套接字耗尽和 DNS 更改问题,由IHttpClientFactory
解决。它还提供扩展以增加应用程序的弹性。
【讨论】:
【参考方案4】:让我补充一下@DarrelMiller 的回答:
如果缩放对您很重要,您应该注意 HttpClient 实例的生命周期。请参考What is the overhead of creating a new HttpClient per call in a WebAPI client?
【讨论】:
以上是关于HttpClientFactory.Create 与新的 HttpClient的主要内容,如果未能解决你的问题,请参考以下文章