zoukankan      html  css  js  c++  java
  • HttpClient到底该不该using?

    HttpClient实例是否应该释放掉?

      从源代码中可以的看到httpClient类最上层实现了IDisposable接口,看到该接口我们下意识就是要用using(自动释放)代码块包含起、或者自己手动调用Disposable方法释放。

    如:

    using(var conn = new SqlConnection(connStr))
    {
            
    }

    这种使用方式是十分正确的,但是由于SqlConnection是比较特殊,这里程序并不会真正的把Connection给释放掉,而是把它丢进连接池(ConnectionPool)中,后面使用的时候在取出来。

    所以这时候问题就来了,httpClient并没有ConnectionPool实现,所以当我们Disposables时它会以 TIME_WAIT的状态继续存活240秒,当程序在短时间内大量创建httpClient对象并销毁时,会占用过多的系统内容,严重的还有可能会消耗完socket port,导致无法建立新的连接。所以我们应该重复使用httpClient对象。

     这句话来自官网:    HttpClient用于在应用程序的整个生存期内实例化一次并重复使用。 实例化每个请求的 HttpClient 类将耗尽重负载下可用的插槽数。 这将导致 SocketException 错误。 下面是正确使用 HttpClient 的示例。 

    public class GoodController : ApiController
    {
        private static readonly HttpClient HttpClient;
    
        static GoodController()
        {
            HttpClient = new HttpClient();
        }
    }

    https://docs.microsoft.com/zh-cn/dotnet/api/system.net.http.httpclient?view=netframework-4.8&viewFallbackFrom=netframework-4

    共用一个 HttpClient 实例的副作用

    共用静态HttpClient 可共用连线避免TIME_WAIT 连线残留,但这也衍生新问题- 当HttpClient 使用xxx.yyy.zzz DNS 名称连上网站,它会记忆DNS 解析结果,
    但因缺乏失效机制快取将永久有效,若DNS 记录修改,必须重新启动程序才会重新解析DNS 取得新IP。在一些实务情境,程式可没法说重启就重启,
    针对此有个简单解法是对特定网站指定 ConnectionLeaseTimeout,强迫 .NET 在一段时间后关闭连线,下次重建连线将可重新解析 DNS。

    var sp = ServicePointManager.FindServicePoint(new Uri("http://xxx.yyy.zzz"));
    sp.ConnectionLeaseTimeout = 600*1000; // 10min

    结论:

    对于httpClient实例不要Disposable(),应该用一个静态变量把它储存起来,供其它地方使用。

  • 相关阅读:
    匿名函数
    内置函数
    基础函数--3
    基础函数(2)
    基础函数(1)
    文件的相关操作
    知识点补充,set集合,深浅copy
    is 和 ==的区别
    Django-form组件中过滤当前用户信息
    Django的常用模块引入整理
  • 原文地址:https://www.cnblogs.com/ROOKIEDEBUG/p/11660591.html
Copyright © 2011-2022 走看看