代码之家  ›  专栏  ›  技术社区  ›  spender

应该释放由httpclientfactory创建的httpclient实例吗?

  •  4
  • spender  · 技术社区  · 7 年前

    因此,我已经在startup.cs中的services集合中注册了一个命名客户机:

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

    现在可以注射 IHttpClientFactory 从我的服务提供商那里。

    使用此 IHTTP客户工厂 ,我想出一个客户端实例:

    var client = httpClientFactory.CreateClient(someServiceName)
    

    从前,在处理 HttpClient 实例 rarely the right thing to do .

    但是,现在我们有了 HttpClientFactory ,这有什么关系吗?应该/可以 client 不用担心就可以处理?例如

    using (var httpClient = httpClientFactory.CreateClient(someServiceName))
    using (var response = await httpClient.PostAsync(somePath, someData))
    {
        var content = await response.Content.ReadAsAsync<SomeResponse>();
        //...
    }
    
    2 回复  |  直到 7 年前
        1
  •  16
  •   Chris Pratt    7 年前

    不,你不应该处置你的客户。更一般地说,你不应该 任何东西 通过DI容器检索,该容器在ASP.NET Core中默认为服务集合。生命周期是由DI容器管理的,所以如果你处理客户端,但是它后来被注入到某个东西中,你会得到一个 ObjectDisposedException . 让容器处理垃圾。

    这实际上是一个常见的混淆 IDisposable 类。你应该亲自实施 不可分的 如果类本身拥有依赖项。如果它的所有依赖项都是 注入的 ,您不应该执行 不可分的 ,因为它没有任何需要处理的东西。同样,不应该丢弃注入到类中的任何内容,因为它不拥有这些依赖项。只处理你特别新买的东西。如果你看不到关键字 new ,你可能不应该处理。

        2
  •  6
  •   Mark Shevchenko    6 年前

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

    证明: HttpClient and lifetime management

    不需要处理客户端。disposal取消传出请求,并保证在调用dispose后不能使用给定的httpclient实例。ihttpclientfactory跟踪并处理httpclient实例使用的资源。HTTPcli客实例通常可以被视为不需要处理的.NET对象。

    检查 source of 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 . 在经典场景中 HTTP客户端 创建的实例 HttpMessageHandler 在自己处理的同时处理它。

    您可以在上面的代码中看到 HTTP客户端 共享的单个实例 HttpMessageHandler 却没有处理掉( disposeHandler: false )

    所以 HttpClient.Dispose 什么都不做。但这并不危险。