2009-09-01 18 views
43

Testuję w warunkach skrajnych aplikację internetową i skonfigurowałem program do testowania systemu Windows, który obraca wiele wątków i wysyła żądanie WWW do każdego z nich.Maksymalna liczba równoczesnych HttpWebRequests

Problem pojawia się następujący komunikat:

01/09/09 11:34:04 Starting new HTTP request on 10 
01/09/09 11:34:04 Starting new HTTP request on 11 
01/09/09 11:34:04 Starting new HTTP request on 13 
01/09/09 11:34:05 Starting new HTTP request on 14 
01/09/09 11:34:05 Starting new HTTP request on 11 
01/09/09 11:34:05 11 has finished! 
01/09/09 11:34:05 Starting new HTTP request on 13 
01/09/09 11:34:05 13 has finished! 
01/09/09 11:34:05 Starting new HTTP request on 14 
01/09/09 11:34:05 14 has finished! 
01/09/09 11:34:05 Starting new HTTP request on 11 
01/09/09 11:34:05 11 has finished! 
01/09/09 11:34:05 Starting new HTTP request on 14 
01/09/09 11:34:05 14 has finished! 
01/09/09 11:34:05 Starting new HTTP request on 13 
01/09/09 11:34:05 13 has finished! 
01/09/09 11:34:05 Starting new HTTP request on 15 
01/09/09 11:34:06 Starting new HTTP request on 11 
01/09/09 11:34:06 11 has finished! 
01/09/09 11:34:06 Starting new HTTP request on 14 
01/09/09 11:34:06 14 has finished! 

który rodzaj wygląda tam maksymalnie 5 wątków, nawet jeśli tworzę 100 a więc:

int numberOfThreads = Convert.ToInt32(txtConcurrentThreads.Text); 

    List<BackgroundWorker> workers = new List<BackgroundWorker>(); 

    for (int N = 0; N < numberOfThreads; N++) 
    { 

     BackgroundWorker worker = new BackgroundWorker(); 
     worker.DoWork += new DoWorkEventHandler(worker_DoWork); 
     worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 
     workers.Add(worker); 
    } 


    foreach(BackgroundWorker worker in workers) 
    { 
     worker.RunWorkerAsync(); 
    } 

Czy ktoś może mnie oświecić co się dzieje?

Dzięki

EDIT: Jeśli jako sugerowane Śpię przez 5 sekund, zamiast HttpWebRequest, to ja rozumiem więcej wątków wypalania, ale nie tyle, ile by się było spodziewać:

01/09/09 11:56:14 Starting new HTTP request on 7 
01/09/09 11:56:14 Starting new HTTP request on 11 
01/09/09 11:56:15 Starting new HTTP request on 12 
01/09/09 11:56:15 Starting new HTTP request on 13 
01/09/09 11:56:16 Starting new HTTP request on 14 
01/09/09 11:56:16 Starting new HTTP request on 15 
01/09/09 11:56:17 Starting new HTTP request on 16 
01/09/09 11:56:17 Starting new HTTP request on 17 
01/09/09 11:56:18 Starting new HTTP request on 18 
01/09/09 11:56:19 Starting new HTTP request on 7 
01/09/09 11:56:19 7 has finished! 
01/09/09 11:56:19 Starting new HTTP request on 11 
01/09/09 11:56:19 11 has finished! 
01/09/09 11:56:19 Starting new HTTP request on 19 
01/09/09 11:56:20 Starting new HTTP request on 20 
01/09/09 11:56:20 Starting new HTTP request on 12 
01/09/09 11:56:20 12 has finished! 

nadal wygląda na to, że zaczynam tylko 2 wątki zaczynając od każdej sekundy, co wydaje mi się potężne powoli. Przypuszczam, że Console.WriteLine może być problemem?

EDIT: I set

ThreadPool.SetMinThreads(100, 4); 

i

System.Net.ServicePointManager.DefaultConnectionLimit = 100; 

i mam następujące wyniki:

01/09/09 14:00:07 Starting new HTTP request on 11 
01/09/09 14:00:07 Starting new HTTP request on 81 
01/09/09 14:00:07 Starting new HTTP request on 82 
01/09/09 14:00:07 Starting new HTTP request on 79 
01/09/09 14:00:07 Starting new HTTP request on 83 
01/09/09 14:00:07 Starting new HTTP request on 84 
01/09/09 14:00:07 Starting new HTTP request on 85 
01/09/09 14:00:07 Starting new HTTP request on 87 
01/09/09 14:00:07 Starting new HTTP request on 88 
... 
01/09/09 14:00:07 84 has finished! Took 323.0323 milliseconds 
01/09/09 14:00:08 88 has finished! Took 808.0808 milliseconds 
01/09/09 14:00:08 96 has finished! Took 806.0806 milliseconds 
01/09/09 14:00:08 94 has finished! Took 806.0806 milliseconds 
01/09/09 14:00:08 98 has finished! Took 801.0801 milliseconds 
01/09/09 14:00:08 80 has finished! Took 799.0799 milliseconds 
01/09/09 14:00:08 86 has finished! Took 799.0799 milliseconds 
01/09/09 14:00:08 92 has finished! Took 799.0799 milliseconds 
01/09/09 14:00:08 100 has finished! Took 812.0812 milliseconds 
01/09/09 14:00:08 82 has finished! Took 1010.101 milliseconds 

więc był w stanie wypchnąć całe mnóstwo wniosków internetowych jednocześnie. Co wydawało się być w kolejce (wołając do serwera STA COM +), więc tego oczekiwałem.

Dzięki za pomoc

+1

Mam pytanie ze swoim rozwiązanie tutaj. zgodnie z msdn (https://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit(v=vs.110).aspx), domyślną wartością jest max int32, która jest o wiele większa niż 100 ustawionych tutaj. Jak to robi różnicę, nawet jeśli nie ustawiłeś jej na 100? Mam na myśli wątpliwość, czy rozwiązałeś go, ustawiając domyślny limit połączenia ServicePointManager, czy raczej ustawiając element connectionManagement w pierwszej odpowiedzi. – foxwendy

+1

@foxwendy Tak, MSDN mówi, że to. int.MaxValue, gdy próbowałem go w .NET 4.5 jest domyślnie ** 2 **. – xmedeko

Odpowiedz

56

Czy wszystkie (lub większość) prośby udających się do tego samego hosta przypadkiem? Istnieje wbudowany limit dla każdego hosta. Możesz to zmienić w app.config w elemencie system.Net connectionManagement.

Inną rzeczą jest to, że pula wątków stopniowo zwiększa swoją liczbę wątków - uruchamia nowy wątek co pół sekundy, IIRC. Czy to może być to, co widzisz? Spróbuj pozbyć się HttpWebRequest z równania - po prostu spać przez kilka sekund zamiast ...

Podejrzewam, że ten ostatni problem jest tym, na który początkowo wpadasz, ale pierwszy sprawi Ci problemy dobrze.

+0

Tak, wszystkie przechodzą do localhost. – Duncan

+0

Nie wiem, czy limit dotyczy lokalnego hosta ... ale jest to na pewno coś, o czym warto pamiętać. Zobacz moją edycję linku do appropraite app.config element. –

+0

Dzięki, zrobimy. – Duncan

48

Istnieje ograniczenie liczby jednoczesnych wychodzących połączeń HTTP. Myślę, że możesz to kontrolować, używając statycznej właściwości System.Net.ServicePointManager.DefaultConnectionLimit przed utworzeniem obiektów HttpWebRequest.

+0

Jeśli ktoś jest ciekawy, domyślną wartością tego ustawienia jest 2 –

1

Jeśli napiszę poniżej znacznika w konfiguracji systemu Windows, to będzie on wykonywany za każdym razem, gdy wykonywany jest poniższy kod. Tak więc za każdym razem, gdy poniżej kodu zostanie wykonany, będę mógł mieć maksymalnie 1000000 brak równoległego żądania/odpowiedzi.

HttpWebRequest POSTRequest = (HttpWebRequest)WebRequest.Create("http://yahoo.com"); 

Tag

<connectionManagement> 
<clear/> 
<add address="*" maxconnection="1000000" /> 
</connectionManagement> 
3

nie słyszałem dużo o tym NET Core.ServicePointManager nie został uwzględniony w .NET rdzeń 1, ale wydaje się być z powrotem w wersji 2. Jednakże na httpclient, można również ustawić maksymalną liczbę połączeń tak:

new HttpClient(new HttpClientHandler 
       { 
        MaxConnectionsPerServer = 100 
       }) 
Powiązane problemy