为什么HttpClient会保持套接字开启?

8

在创建、使用和处理多个HttpClient时,我注意到有一些套接字处于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头的值为close来防止这种情况发生吗?

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

你看过这个吗?:https://dev59.com/OFLTa4cB1Zd3GeqPY0Ii - Brandon
如果您需要向服务器发送额外的请求,这可能是一种优化解决方案。 - Bradley Uffner
可能是如何防止套接字/端口耗尽?的重复问题。 - Igor
最好在您的库中创建此类型的静态实例并重复使用它。 - Igor
2
请查看此链接:http://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ - Bradley Uffner
2个回答

9
每个 HttpClient 实例都会为了更好的性能而池化连接,但这意味着每个实例在不使用连接时也会将连接保持在 TIME_WAIT 状态。 HttpClient 实际上是线程安全、可重入且设计用于长时间使用;它不应该被处理掉(尽管它实现了 IDisposable)直到你的程序退出。你应该在整个应用程序中共享一个 HttpClient 实例以利用它的优点。
更多信息可在这里找到。

1
当查看如何设置标头值时,这变得更加明显。在HttpClient上直接设置它们是DefaultRequestHeaders,这意味着HttpContent将具有与请求唯一的标头,并且HttpClient将被重用。最初,IDisposable继承使我感到困惑。还有80%的示例处置了HttpClient。 - Benjamin Soddy

1

来自MSDN

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

HttpClient会池化连接以提高性能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接