HttpClientFactory.Create与new HttpClient的区别

79

我很好奇 HttpClientFactory 的目的。MSDN上没有关于它存在的描述(参见链接)。

有一些带有更专业参数的Create 方法,但大多数时候我想知道没有参数的调用和普通构造函数之间的区别。


var httpClient = HttpClientFactory.Create();

VS

var httpClient = new HttpClient();

在大多数例子中,我看到使用new HttpClient(),没有任何using语句,即使HttpClient继承自IDisposable

由于HttpClient类继承自IDisposable,工厂是否进行了一些池化或缓存?有性能优势吗,还是无关紧要?

更新- .NET Core 2.1中的IHttpClientFactory

请注意,自提出此问题以来,已发布了新版本的.NET,.NET Core 2.1引入了一种新的和改进的方法来获取HTTP客户端。

有关在.NET Core中使用IHttpClientFactory的详细信息,请参阅下面的Ali Bayat答案。

但是,我将Darrel Miller的答案保留为接受的答案,因为这是针对在.NET Framework v4.8之前提出该问题的情况的正确答案。

在.NET 5中,.NET Framework和.NET Core之间的差异将会被调整,您应该使用IHttpClientFactory

更新- 官方指导

微软已添加了有关处置行为和推荐使用的文档:https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/httpclient-guidelines


4个回答

71
工厂是一个辅助方法,用于在管道中有多个DelegatingHandler时创建客户端。Delegating处理程序需要连接在一起形成一个管道。这个工厂允许您将处理程序作为数组传递进来,工厂将负责将它们连接在一起。
我相信(不要完全相信我的话),CreatePipeline方法可能在服务器端用于构建Web API HttpServer的消息处理管道。
我很高兴你没有看到很多关于在HTTPClient周围使用块的例子,因为我一直在反对这种做法已经有好几年了。虽然HttpClient实现了可释放接口,但它只在处理异常情况下进行释放,即在请求进行中时被销毁。HttpClient实例应该是长时间存在的。强制释放它们会关闭底层的TCP连接,这是应该被池化的。HttpClient是线程安全的,可以被不同的线程安全地多次使用。这是它的预期使用方式,而不是我经常看到的单次使用、使用块的模式。

1
感谢您的回复!深入研究后,我也发现了这篇SO帖子,David Faivre在其中解释了当重复创建太多HttpClient时可能会出现的问题。 - Bart Verkoeijen
@Darrel,如果我有一个长时间运行的HttpClient,但最终我会摆脱它,那么在那个时候,我需要手动调用dispose吗?还是可以让它超出范围并让GC来处理它? - SlaterCodes
4
@Darrel,请注意,尽管大多数方法是线程安全的,但实例成员不是(与大多数.NET Framework一样)-请参见http://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx - Dave Black
那么对于未命名的客户端(例如针对不同的baseUrl),httpCLientFactory.Create()是否具有与命名客户端相同的所有优点(不涉及自定义设置和功能,如Polly)? - Ssss

36

IHttpClientFactory 提供以下好处:

  1. 命名和配置逻辑 HttpClient 实例。
  2. 构建一个 出站请求中间件 来管理围绕 HTTP 请求的 横切关注点
  3. Polly 集成以进行瞬态故障处理。
  4. 通过管理 HttpClient 生命周期来避免常见的 DNS 问题。
  5. 为由工厂创建的客户端发送的所有请求添加 日志记录

了解更多


2
感谢您添加这个指导,因为随着在.NET Core中引入IHttpClientFactory,它是比此问题被提出时可用的选项更好的替代方案。 - Bart Verkoeijen
2
我很好奇,是否有一个实际的.NET Core类来实现IHttpClientFactory,即一个具体类?唯一使用它的方法似乎是使用IoC容器并调用services.AddHttpClient()。 - bytedev
1
IHttpClientFactory 是 DefaultHttpClientFactory 实现的一个接口。 - Ali Bayat
3
截至今天,似乎仍然没有一种方法可以在不依赖于微软自己的 DI 容器的情况下使用具体实现。关于这个问题正在这里进行讨论:https://github.com/dotnet/aspnetcore/issues/28385 - silkfire
1
DefaultHttpClientFactory 是一个内部类,因此您无法从自己的代码中实例化它。 - silkfire

7

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接