经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
C# HttpClient使用和注意事项,.NET Framework连接池并发限制
来源:cnblogs  作者:XSpringSun  时间:2023/2/24 9:07:33  对本文有异议

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

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

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

使用方式

  1. 使用静态变量。
  1. static readonly HttpClient httpClient = new HttpClient();
  1. 使用单例模式
  1. public class HttpClientInstance
  2. {
  3. private static readonly HttpClient _HttpClient;
  4. static HttpClientInstance()
  5. {
  6. _HttpClient = new HttpClient();
  7. }
  8. public static HttpClient GetHttpClient()
  9. {
  10. return _HttpClient;
  11. }
  12. }

实例化参数

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

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

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

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

  1. HttpClientHandler httpClientHandler = new HttpClientHandler();
  2. //最大并发连接数
  3. httpClientHandler.MaxConnectionsPerServer = 100;
  4. HttpClient httpClient=new HttpClient(httpClientHandler);
  5. //超时设置
  6. 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的连接池并发数需要修改默认值。

  1. System.Net.ServicePointManager.DefaultConnectionLimit = n;

然后再实例化RestClient。

原文链接:https://www.cnblogs.com/SunSpring/p/17148228.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号