为什么HttpClient保持套接字打开

本文关键字:套接字 HttpClient 为什么 | 更新日期: 2023-09-27 18:09:02

在创建、使用和处理多个HttpClients时,我注意到有一些处于TIME_WAIT状态的套接字处于打开状态。

例如,运行以下程序后:

using System.Net.Http;
namespace HttpClientTest
{
    public class Program
    {
        public static void Main(string[] args)
        {
            for (var i = 0; i < 10; i++)
            {
                using (var httpClient = new HttpClient())
                {
                   var result = httpClient.
                        GetAsync("http://stackoverflow.com/").
                        Result;
                }
            }
        }
    }
}

我注意到netstat的套接字是打开的:

TCP    10.200.60.168:2722     151.101.193.69:http    TIME_WAIT
TCP    10.200.60.168:2751     151.101.193.69:http    TIME_WAIT
TCP    10.200.60.168:2752     151.101.193.69:http    TIME_WAIT
TCP    10.200.60.168:2753     151.101.193.69:http    TIME_WAIT
TCP    10.200.60.168:2754     151.101.193.69:http    TIME_WAIT
TCP    10.200.60.168:2755     151.101.193.69:http    TIME_WAIT
TCP    10.200.60.168:2756     151.101.193.69:http    TIME_WAIT
TCP    10.200.60.168:2757     151.101.193.69:http    TIME_WAIT
TCP    10.200.60.168:2758     151.101.193.69:http    TIME_WAIT
TCP    10.200.60.168:2759     151.101.193.69:http    TIME_WAIT

这是预期的行为吗?我是否需要显式地将Connection标头值设置为关闭以防止这种情况发生?

httpClient.
    DefaultRequestHeaders.
    Connection.
    Add("close");

为什么HttpClient保持套接字打开

HttpClient的每个实例都将其连接池化以获得更好的性能,但这意味着每个实例在未使用时也会将池化的连接留在TIME_WAIT中。

HttpClient实际上是线程安全的、可重入的,并且是为扩展使用而设计的;在程序退出之前,不应该处理它(即使它实现了IDisposable(。您应该在整个应用程序中共享HttpClient的一个实例来利用这一点。

更多信息可以在这里找到。

来自MSDN

每个HttpClient实例都使用自己的连接池,将其请求与其他HttpClient实例执行的请求隔离开来。

HttpClient池连接以获得更好的性能。