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 解释了在重复更新太多HttpClients 时可能出现的问题。 @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的主要内容,如果未能解决你的问题,请参考以下文章