2017-09-12 65 views
0

我想使用多線程的Web請求,但我沒有得到我期望的性能。多線程的Web請求性能問題

我使用4核心的計算機運行,上載速度爲1 Gbps,下載速度爲1 Gbps。

對於我正在下載谷歌主頁的測試。

從谷歌網頁的數據大小是〜50 KB。

我同時發送1000個請求,我除了完成〜2秒內的所有請求,但它需要超過20秒才能完成

我的代碼看起來是這樣的:

 bool success = ThreadPool.SetMinThreads(workerThreads: 2000, completionPortThreads: 1000); 
     success = ThreadPool.SetMaxThreads(2000, 2000); 
     DateTime dt = DateTime.UtcNow; 
     Parallel.For(0, 1000, (num) => 
     { 
      string url = "https://www.google.co.il/?gfe_rd=cr&dcr=0&ei=OZy3WcmoMY7b8Affj4F4&gws_rd=ssl"; 
      using (WebClient web = new WebClient()) 
      { 
       byte[] bytes = web.DownloadData(url); 
      } 
     } 
     ); 
     double sec = (DateTime.UtcNow - dt).TotalSeconds; 
     Console.WriteLine(sec); 
+2

https://stackoverflow.com/questions/1361771/max-number-of-concurrent-httpwebrequests –

+0

另外,注意'Parallel.For'將只使用一個每個核心線程(所以在你的情況下,四個線程)。這不是用於I/O綁定操作的正確工具 –

+0

另外,默認情況下,ServicePiontManager將任何主機的併發請求限制爲2個。您需要更改默認的連接限制,或者查看向您的app.config文件添加connectionManagement部分。 –

回答

0

我覺得在你的情況下,更好的選擇是使用HttpClient進行顯式異步操作,並讓Windows管理線程池本身。

Stopwatch sw = new Stopwatch(); 
sw.Start(); 

for (int i = 0; i < 1000; i++) 
{ 
    var httpClient = new HttpClient(); 
    results[i] = httpClient.GetByteArrayAsync(@"https://www.google.co.il/?gfe_rd=cr&dcr=0&ei=OZy3WcmoMY7b8Affj4F4&gws_rd=ssl"); 
} 

var status = Task.WhenAll(results); //WhenAny if you can process results independently 
var pages = status.Result; 
sw.Stop(); 
double sec = sw.Elapsed.TotalSeconds; 
Console.WriteLine(sec); 

邊注:請考慮使用Stopwatchtime measurement

-1

的解決方案是:

 System.Net.ServicePointManager.DefaultConnectionLimit = int.MaxValue; 
+4

這個答案很混亂,缺乏上下文。你應該添加一些描述 –