首页 > 编程语言 >C# HttpClient使用和注意事项,.NET Framework连接池并发限制

C# HttpClient使用和注意事项,.NET Framework连接池并发限制

时间:2023-02-24 09:14:47浏览次数:43  
标签:请求 并发 C# Framework 实例 NET 超时 连接 HttpClient

System.Net.Http.HttpClient 类用于发送 HTTP 请求以及从 URI 所标识的资源接收 HTTP 响应。 HttpClient 实例是应用于该实例执行的所有请求的设置集合,每个实例使用自身的连接池,该池将其请求与其他请求隔离开来。 从 .NET Core 2.1 开始,SocketsHttpHandler 类提供实现,使行为在所有平台上保持一致。

HttpClient实例是执行网络请求的设置集合,每个实例会使用一个连接池。通过这段描述我们知道实际使用HttpClient的时候我们只需要实例化一个就行了,在处理程序实例内池连接,并在多个请求之间重复使用连接。也就是官方提倡的使用单个实例,如果每次请求就实例化一个HttpClient,则会创建不必要的连接降低性能,并且TCP 端口不会在连接关闭后立即释放。

所以如果是大批量创建HttpClient请求则大量负载下可用的套接字数将耗尽,这种耗尽将导致 SocketException 错误。

使用方式

  1. 使用静态变量。
static readonly HttpClient httpClient = new HttpClient();

  1. 使用单例模式
    public class HttpClientInstance
    {
        private static readonly HttpClient _HttpClient;

        static HttpClientInstance()
        {
            _HttpClient = new HttpClient();
        }

        public static HttpClient GetHttpClient()
        {
            return _HttpClient;
        }
    }

实例化参数

可以通过构造参数(如 HttpClientHandler (或 SocketsHttpHandler .NET Core 2.1 或更高版本) )作为构造函数的一部分来配置其他选项。 实例化HttpClient后无法更连接属性,因此,如果需要更改连接属性,则需要创建新的 HttpClient 实例。

配置可以在构造期间配置 HttpClientHandler 或 SocketsHttpHandler 传入,SocketsHttpHandler可以设置额外参数包括 MaxConnectionsPerServer, PooledConnectionIdleTimeout、PooledConnectionLifetime、ConnectTimeout。

  • MaxConnectionsPerServer:HttpClient 对象所允许的最大并发连接数。
  • PooledConnectionIdleTimeout: PooledConnectionLifetime 指定的时间范围过后,系统会关闭连接,然后创建一个新连接。
  • PooledConnectionLifetime:指定要用于连接池中每个连接的超时值。 如果连接处于空闲状态,则连接会立即关闭;否则,连接在当前请求结束时关闭。
  • ConnectTimeout:指定在请求需要创建新的 TCP 连接时使用的超时。 如果发生超时,将取消请求 Task
var handler = new SocketsHttpHandler
{
    PooledConnectionLifetime = TimeSpan.FromMinutes(15)
};
var httpClient = new HttpClient(handler);

在.NET Framework 只能使用HttpClientHandler,且没有PooledConnectionIdleTimeout和PooledConnectionLifetime等参数。

HttpClientHandler httpClientHandler = new HttpClientHandler();
//最大并发连接数
httpClientHandler.MaxConnectionsPerServer = 100;

HttpClient httpClient=new HttpClient(httpClientHandler);
//超时设置
httpClient.Timeout = new TimeSpan(5000);

可以是设置MaxConnectionsPerServer,可以设置Timeout。Timeout 为来自 HttpClient 实例的所有 HTTP 请求设置默认超时。 超时仅适用于导致启动请求/响应的 xxxAsync 方法。 如果达到超时,则会 Task 取消该请求。这个超时时间是包含从请求到响应的整个时间段,而不像上面参数可以设置连接超时。

请求实现

HttpClient这是一个高级 API,用于包装其运行的每个平台上可用的较低级别功能。

在每个平台上, HttpClient 尝试使用最佳可用传输:
image

注意事项

在上面实现可以看到在不同的框架下HttpClient的实现是不一样的,在.NET Framework下是使用HttpWebRequest支持。

所以还会受限HttpWebRequest的实现,如果我们要启用多线程高频率调用接口,那么这里要注意HttpWebRequest的连接并发的数量限制。HttpWebRequest通过ServicePoint设置,我们通过反编译看到HttpWebRequest构造函数。
image

ServicePoint.DefaultConnectionLimit获取允许的最大并发连接数。 对于 ASP.NET 托管的应用程序,默认连接限制为 10,对于所有其他应用程序,默认连接限制为 2。DefaultConnectionLimit 对现有 ServicePoint 对象没有影响;它只影响更改后初始化的对象。如果未直接或通过配置设置此属性的值,则该值默认为常量 DefaultPersistentConnectionLimit

image

如果是应用连接池默认只有2个并发,所以当你启用很多线程的时候实际效率是不会提升的,一直只有两个并发在阻塞排队,如果请求比较耗时后面的请求还有异常的可能。

因此当你使用多线程的时候要注意初始化HttpClient的httpClientHandler.MaxConnectionsPerServer = n;该参数用于设置。

RestSharp

平时我们可能使用RestSharp 用于网络请求,实际也是在HttpWebRequest上的封装,在官网我们可以看到如下说明:
image

在最新的v107换成了HttpClient,以前的版本也是HttpWebRequest。如果要设置RestSharp的连接池并发数需要修改默认值。

System.Net.ServicePointManager.DefaultConnectionLimit = n;

然后再实例化RestClient。

标签:请求,并发,C#,Framework,实例,NET,超时,连接,HttpClient
From: https://www.cnblogs.com/SunSpring/p/17148228.html

相关文章

  • VS Code 智能提示 插件
    Vue3Snippets HTMLSnippets  ......
  • pycharm的下载和安装
    1.下载直接在官网下载:https://www.jetbrains.com/pycharm/download/  2.安装2.1打开刚下载好的文件,如下红框中文件。  2.2打开后如下,点击next......
  • 调式源码解决 seata 报错 can not get cluster name 问题
    最近在使用SpringCloud整合分布式事务seata,项目启动之后,控制台一直报错:cannotgetclusternameinregistryconfig'service.vgroupMapping.nacos-provide-order-sea......
  • linux 移植 i2CTools
    一、I2C-Tools介绍i2c-tools工具是一个专门用来调试i2c的。并且是开源的。它可以:1、检测有几组i2c总线在系统上。2、查看挂载在i2c上面设备寄......
  • RocketMQ - 消费者启动机制
    RocketMQ客户端中有两个独立的消费者实现类:org.apache.rocketmq.client.consumer.DefaultMQPullConsumer和org.apache.rocketmq.client.consumer.DefaultMQPushConsumer......
  • C#轮转图
     usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingDG.Tweening;publicclassRotationChart:MonoBehaviour{public......
  • 使用JsonTextReader提高Json.NET反序列化的性能
    一、碰到的问题在服务器的文件系统上有一个业务生成的BigTable.json文件,其可能包含的JSON字符串很大,同时里边的集合会包含很多的记录;我们使用以下的代码来反序列化,虽然使......
  • IDEA&Eclipse快捷键对照表
    在Mac中commond替换Ctrloption替换AltIDEACommentEclipseCommentRemarkCtrl+Alt+H调用层次,方法调用Ctrl+Alt+H开放的调用层次结构Alt+F7查找光标......
  • 一文读透react精髓
    学和使用react有一年多了,最近想在梳理一下react基础知识,夯实基础,激流勇进~关于reacr-router,redux,redux-saga后续都会慢慢输出,希望各位看官老爷持续关注~~要是能给个赞......
  • 阿里前端二面必会react面试题指南
    这段代码有什么问题吗?这段代码有什么问题:this.setState((prevState,props)=>{return{streak:prevState.streak+props.count,};});答案:没有什么问......