我敢肯定,我们所有人都读过这篇在2016年引起轰动的文章:https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
对于那些没有的人,总之(强调我的):
您不必为每次执行创建新的
HttpClient
实例,而应在应用程序的整个生命周期内共享一个HttpClient实例。
现在,考虑一个使用HttpClient
使用其他Web服务的ASP.NET Core应用程序。其HttpClient
的用法可分为两种一般情况:
未经验证或使用网站自己的凭据的传出请求-在这种情况下,单个HttpClient
实际上可以由程序的所有部分共享。
代表网站当前访问者之一发出的传出请求-或使用特定于请求的凭据的请求。
HttpClient
实例 ,但必须注意不要改变其状态,例如,通过设置DefaultRequestHeaders
(例如,使用{{ 1}}扩展方法)。实际上,在ASP.NET Core中使用SetBearerToken
的所有指南都指出:
HttpClient
实例作为构造函数参数的POCO,以及任何其他DI服务)。HttpClient
注册这些类型的客户端。
services.AddHttpClient<TClient>()
注册为瞬时实例。TClient
注册为瞬时实例。ITypedHttpClientFactory<TClient>
注册为单个 IHttpClientFactory
注册为单个 现在讨论了这个问题,我将引起您的注意:
IHttpMessageHandlerFactory
实例必须是长寿命的。HttpClient
DI系统确实可以确保HttpClient
实例是短命的。但是,如果博客文章确实应该在谈论底层的HttpClient
(这是 real HttpClient实现,它被简单包装),那么通过薄壳HttpMessageHandler
)-而不是外部class HttpClient
?
令人困惑的是,人们也报告了使用寿命长的class HttpClient
实例的问题,并介绍了其他所有涉及HttpClient
的变通办法,这让我感到不舒服:
static class ServicePointManager
。ServicePointManager
ConnectionLeaseTimeout
!在我看来,这不合适。我的问题:
ServicePointManager.FindServicePoint()
实例是真的是长寿还是短寿?HttpClient
实例?HttpMessageHandler
或HttpClient
实例具有长寿命:
HttpMessageHandler
问题?ServicePointManager
,而是在每个HttpClient.DefaultRequestHeaders
上显式设置Authorization
(Cookies或凭据)标头?还有另一种方法可以减少麻烦吗?HttpRequestMessage
添加这些标头吗?那么,这个提议的处理程序的DI注册应该是什么?如果DelegatingHandler
实例(而不是HttpClient
实例)是短命的:
HttpMessageHandler
(和HttpClient.DefaultRequestHeaders
)吗?SetBearerToken()
实例的生存期策略是什么?HttpMessageHandler
(和HttpClient.DefaultRequestHeaders
)吗?如果SetBearerToken()
实例和 HttpClient
实例是短命的:
HttpMessageHandler
会采取什么措施来减轻这些问题吗?