是否应该释放由 HttpClientFactory 创建的 HttpClient 实例?

因此,我在 Startup.cs 中注册了一个具名客户端和服务集合:

services.AddHttpClient(someServiceName,
client => client.BaseAddress = baseAddress);

现在可以从我的服务提供商注入 IHttpClientFactory

使用这个 IHttpClientFactory,我想象出一个客户端实例:

var client = httpClientFactory.CreateClient(someServiceName)

很久以前,有必要非常小心地处理 HttpClient实例,因为它是 很少做正确的事

但是,现在我们有了 HttpClientFactory,这还重要吗? 这个 client应该/可以放心处理吗? 例如。

using (var httpClient = httpClientFactory.CreateClient(someServiceName))
using (var response = await httpClient.PostAsync(somePath, someData))
{
var content = await response.Content.ReadAsAsync<SomeResponse>();
//...
}
16064 次浏览

没有。你不应该处理掉你的客户。更一般地说,不应该释放通过 DI 容器检索到的 什么都行,在 ASP.NET Core 中,DI 容器默认是服务集合。生存期是由 DI 容器管理的,因此如果您释放了客户机,但是稍后将其注入到某个内容中,您将获得一个 ObjectDisposedException。让集装箱处理处置。

这实际上是与 IDisposable类常见的混淆。如果您的类本身拥有依赖项,那么您个人应该只实现 IDisposable。如果它的所有依赖项都是 注射,那么您就不应该实现 IDisposable,因为它没有任何需要处理的东西。同样,不应该释放注入到类中的任何东西,因为它不拥有那些依赖项。只处理你特别新添的东西。如果您没有看到关键字 new,那么您可能不应该进行处理。

不需要调用 Dispose方法,但是如果出于某些原因需要,仍然可以调用它。

证据: HttpClient 和生命周期管理

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

检查 DefaultHttpClientFactory来源:

public HttpClient CreateClient(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}


var handler = CreateHandler(name);
var client = new HttpClient(handler, disposeHandler: false);


var options = _optionsMonitor.Get(name);
for (var i = 0; i < options.HttpClientActions.Count; i++)
{
options.HttpClientActions[i](client);
}


return client;
}

HttpMessageHandler实例存储 HttpClient的非托管资源。在经典场景中,HttpClient创建 HttpMessageHandler的实例,并在自己处理的同时进行处理。

您可以在上面的代码中看到,HttpClient的不同实例共享 HttpMessageHandler的单个实例,并且不释放它(disposeHandler: false)。

所以,HttpClient.Dispose的呼叫没有任何作用,但它并不危险。