C# - 如何同时执行多个 Web 请求

Posted

技术标签:

【中文标题】C# - 如何同时执行多个 Web 请求【英文标题】:C# - how to do multiple web requests at the same time 【发布时间】:2019-02-19 15:00:22 【问题描述】:

我写了一个代码来检查 url,但是,ir 的工作速度真的很慢。我想尝试让它同时在几个 url 上工作,例如 10 个 url,或者至少让它尽可能快。

我的代码:

Parallel.ForEach(urls, new ParallelOptions 
  MaxDegreeOfParallelism = 10
, s => 
  try 
    using(HttpRequest httpRequest = new HttpRequest()) 
      httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0";
      httpRequest.Cookies = new CookieDictionary(false);
      httpRequest.ConnectTimeout = 10000;
      httpRequest.ReadWriteTimeout = 10000;
      httpRequest.KeepAlive = true;
      httpRequest.IgnoreProtocolErrors = true;
      string check = httpRequest.Get(s + "'", null).ToString();
      if (errors.Any(new Func < string, bool > (check.Contains))) 
        Valid.Add(s);
        Console.WriteLine(s);
        File.WriteAllLines(Environment.CurrentDirectory + "/Good.txt", Valid);
      
    
   catch 

  
);

【问题讨论】:

另外,顺便说一句,一些 Web 服务器可能不会并行处理您的请求(因为它可能看起来像 DoS 攻击,或者它只是限制了来自 IP 的连接数)。仅仅因为您并行发出 10 个请求并不意味着 Web 服务器将并行向您返回数据。它可能仍会将数据返回给您,就像您发送它们一样发送请求 -> 接收响应 -> 发送 -> 接收,等等。 MaxDegreeOfParallelism 考虑您机器的处理能力,而不是集合中的记录数。如果您有双核,它将并行处理 2 条记录。另一方面,浏览器可以并行发送更多请求,但不幸的是服务器不能。 那么我怎样才能让它更快呢?其他工具如何真正快速?甚至与我做同样事情的工具 @RohitRamname 等待 10 个 HTTP GET 将消耗多少处理能力?让我猜猜:零? @SirRufo,我想也是。我也可以使用这个问题的解决方案。 【参考方案1】:

您的服务调用不太可能是CPU-bound。因此,启动更多线程来处理负载可能不是最好的方法——如果你使用asyncawait,你将获得更好的吞吐量,如果可以的话,使用更现代的HttpClient 而不是 HttpRequest 或 HttpWebRequest .

下面是一个例子:

var client = new HttpClient();

//Start with a list of URLs
var urls = new string[]
    
        "http://www.google.com",
        "http://www.bing.com"
    ;

//Start requests for all of them
var requests  = urls.Select
    (
        url => client.GetAsync(url)
    ).ToList();

//Wait for all the requests to finish
await Task.WhenAll(requests);

//Get the responses
var responses = requests.Select
    (
        task => task.Result
    );

foreach (var r in responses)

    // Extract the message body
    var s = await r.Content.ReadAsStringAsync();
    Console.WriteLine(s);

【讨论】:

谢谢,我试试 这也适用于 POST 请求吗?如果可以,请告诉我怎么做,谢谢。 由于某种原因,我一直遇到请求消息已发送无法重新发送。而不是string[] 我创建了List&lt;HttpRequestMessage&gt; 然后var requests = httpRequestMessages.Select(h =&gt; Client.SendAsync(h)) @HamzaKhanzada 听起来像是网络问题,或者可能是服务问题;很可能与客户端代码无关。 @MichaelBrown 这个问题是关于发送多个请求,而不是发送一个包含多个文件的请求(这是相当不同的)。我建议你问一个单独的问题。【参考方案2】:

尝试如下操作。

Parallel.ForEach(urls, new ParallelOptions  MaxDegreeOfParallelism = Environment.ProcessorCount - 1 

至少留1可以保证所有的核心都用完,这样你的机器就不会内存不足了。

另外,请考虑@KSib 评论。

【讨论】:

感谢您的回答,但是,maxDegree = 10 时工作得更快

以上是关于C# - 如何同时执行多个 Web 请求的主要内容,如果未能解决你的问题,请参考以下文章

如何测试模拟多个并发请求的Web服务

在调度屏障中同时执行多个块

Web 服务器如何在单个端口 (80) 上一次处理多个用户的传入请求?

Servlet容器如何同时来处理多个请求

C# 执行 Web GET 请求

C# 执行基本的 Web POST 请求