【问题标题】:Multi threaded web requests performance issue多线程 Web 请求性能问题
【发布时间】:2017-09-12 09:10:16
【问题描述】:

我想使用多线程 Web 请求,但我没有获得预期的性能。

我正在使用具有 4 核、1 Gbps 上传和 1 Gbps 下载的计算机运行。

为了测试,我正在下载谷歌主页。

来自 google 页面的数据大小约为 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);

【问题讨论】:

  • 另外,请注意Parallel.For 每个核心仅使用一个线程(因此在您的情况下,四个线程)。这不是用于 I/O 绑定操作的正确工具
  • 此外,ServicePintManager 默认限制您对任何主机的 2 个并发请求。您需要更改默认连接限制,或考虑将 connectionManagement 部分添加到您的 app.config 文件中。

标签: c# multithreading httpwebrequest webrequest


【解决方案1】:

我认为在您的情况下,更好的选择是使用 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);

旁注:请考虑将Stopwatch 用于time measurement

【讨论】:

    【解决方案2】:

    解决办法是:

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

    【讨论】:

    • 这个答案令人困惑并且缺乏上下文。你应该添加一些描述
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多