Jak mogę zapobiec wyczerpaniu gniazd / portów?

Próbuję przetestować witrynę, uderzając ją żądaniami w wielu wątkach. Każdy wątek jest wykonywanyn czasy. (w pętli for)

Mam jednak problemy. W szczególności wyjątek WebException („Nie można połączyć się ze zdalnym serwerem”) z wewnętrznym wyjątkiem:

Nie można wykonać operacji na gnieździe, ponieważ w systemie brakowało wystarczającej ilości miejsca na bufor lub kolejka była pełna 127.0.0.1:52395

Próbuję uruchomić 100 wątków przy 500 iteracjach na wątek.

Początkowo używałemHttpWebRequest w System.Net, aby wysłać żądanie GET do serwera. Obecnie używamWebClient ponieważ założyłem, że każda iteracja używa nowego gniazda (więc 100 * 500 gniazd w krótkim czasie). Zakładałem, że WebClient (który jest tworzony raz na wątek) używałby tylko jednego gniazda.

Nie potrzebuję 50 000 otwartych gniazd od razu, ponieważ chciałbym wysłać żądanie GET, odebrać odpowiedź i zamknąć gniazdo, uwalniając je do użycia w następnej iteracji pętli. Rozumiem, że byłoby to problemem

Jednak nawet w przypadku WebClient żąda się wielu gniazd, co powoduje powstanie wielu gniazdTIME_WAIT tryb (sprawdzany za pomocą netstat). Powoduje to, że inne aplikacje (takie jak przeglądarki internetowe) zawieszają się i przestają działać.

Mogę obsługiwać test z mniejszą liczbą iteracji i / lub mniejszą liczbą wątków, ponieważ wydaje się, że gniazda ostatecznie kończą ten stan OCZEKIWANIA CZASU. Nie jest to jednak rozwiązanie, ponieważ nie sprawdza odpowiednio możliwości serwera WWW.

Pytanie:

Jak jawnie zamknąć gniazdo (od strony klienta) po każdej iteracji wątku, aby zapobiec stanom TIME_WAIT i wyczerpaniu gniazda?

Kod:

Klasa, która otacza HttpRequest

Edytować: Wrapped WebClient w użyciu, więc nowy jest tworzony, używany i usuwany dla każdej iteracji. Problem nadal występuje.

  public sealed class HttpGetTest : ITest {
    private readonly string m_url;

    public HttpGetTest( string url ) {          
        m_url = url;
    }

    void ITest.Execute() {
        using (WebClient webClient = new WebClient()){
            using( Stream stream = webClient.OpenRead( m_url ) ) {          
            }
        }
    }
}

Część mojej klasy ThreadWrapperClass, która tworzy nowy wątek:

public void Execute() {
    Action Hammer = () => {
        for( int i = 1; i <= m_iterations; i++ ) {
            //Where m_test is an ITest injected through constructor
            m_test.Execute();
        }       
    };
    ThreadStart work = delegate {
        Hammer();
    };
    Thread thread = new Thread( work );
    thread.Start();
}

questionAnswers(5)

yourAnswerToTheQuestion