2016-09-27 18 views
5

Podczas tworzenia, używania i usuwania kilku HttpClients zauważam, że w statusie TIME_WAIT są otwarte gniazda.Dlaczego HttpClient pozostawia gniazda otwarte?

Na przykład po uruchomieniu następuje:

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; 
       } 
      } 
     } 
    } 
} 

zauważam z netstat, że gniazda są otwarte:

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 

Jest to oczekiwane zachowanie? Czy muszę jawnie ustawić wartość nagłówka połączenia, aby ją zamknąć, aby temu zapobiec?

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

Widziałeś to ?: http://stackoverflow.com/questions/4306372/preventing-time-wait-using-net-async-api – Brandon

+0

Może to być optymalizacja w przypadku, gdy potrzebujesz dodatkowych próśb do serwer. –

+0

Możliwy duplikat [W jaki sposób zapobiec wyczerpaniu gniazda/portu?] (Http://stackoverflow.com/questions/11569441/how-do-i-prevent-socket-port-exhaustion) – Igor

Odpowiedz

6

Każda instancja HttpClient łączy swoje połączenia dla lepszej wydajności, ale oznacza to, że każda instancja również pozostawia połączone połączenia w TIME_WAIT, gdy nie są używane.

HttpClient jest w rzeczywistości bezpieczny dla wątków, wielokrotny i przeznaczony do długotrwałego użytkowania; nie należy go usuwać (nawet jeśli implementuje się IDisposable) do czasu zakończenia programu. Powinieneś udostępnić jedną instancję HttpClient w całej aplikacji, aby z niej skorzystać.

Więcej informacji można znaleźć here.

+0

Staje się to bardziej oczywiste, patrząc na sposób ustawiania wartości nagłówka. Bezpośrednio na HttpClient są to wartości DefaultRequestHeaders, co oznacza, że ​​HttpContent będzie miał nagłówki unikalne dla żądania, a HttpClient zostanie ponownie użyty. Dziedziczenie IDisposable początkowo mnie wyrzucało. A także 80% próbek odrzucających HttpClient. –

1

Od MSDN

każdym przypadku HttpClient używa własnej puli połączeń, izolowanie swoich żądań od wniosków zawartych przez innych httpclient przypadkach.

HttpClient połączeń basenowych dla lepszej wydajności.