【问题标题】:Parallel async HttpWebRequests with different proxies. How to maximize performance?具有不同代理的并行异步 HttpWebRequest。如何最大化性能?
【发布时间】:2015-04-01 08:19:49
【问题描述】:

我正在编写一个应用程序,它需要对来自不同代理的博彩网站进行大量并行 httpwebrequests。我使用不同代理的原因是,如果有很多请求,博彩公司可以禁止 ip。我的目标是尽快获得最新的网站内容。 这是我的所有设置的代码:

        ServicePointManager.DefaultConnectionLimit = 1000;
        ServicePointManager.Expect100Continue = false;
        ServicePointManager.UseNagleAlgorithm = false;

        for (var i = 0; i < proxyCollection.Count; i++)
        {
            var proxyLocal = proxyCollection[i];
            var iLocal = i;
            Task.Run(async () =>
                {
                    var httpWebRequest = (HttpWebRequest) WebRequest.Create(String.Format("https://bookmaker.com/page{0}", iLocal));
                    httpWebRequest.Proxy = proxyLocal;
                    httpWebRequest.PreAuthenticate = true;
                    httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

                    using (var httpWebResponse = (HttpWebResponse) await httpWebRequest.GetResponseAsync())
                    using (var responseStream = httpWebResponse.GetResponseStream())
                    using (var streamReader = new StreamReader(responseStream))
                    {
                        var stringContent = await streamReader.ReadToEndAsync();
                        //Here i'm processing new data. It works pretty fast, so this isn't a problem
                        ProcessStringContent(stringContent);
                    }
                });            
         }

而且这段代码的运行速度并没有我预期的那么快。

第一个问题是奇怪的原因是所有 r请求都不会同时开始。正如我在任务管理器中看到的,加载有两个或更多最大值。此外,我有一个非常快速的代理,proxyCollection 包含它。但是如果我在上面的代码之后使用await Task.Delay(5000),在某些情况下,当我的快速代理通过请求 5000 毫秒时甚至都不会启动!

第二个问题是所有任务执行的总时间很慢。我预计如果一个请求需要 200-300 毫秒来执行,那么并行和异步的 100 个请求需要更多的时间。但有时这个“更多”是10-20倍。我怀疑,有问题。

第三个问题是,当我运行这段代码时,它会冻结 UI(不是完全冻结,而是 UI 滞后)。我读到WebRequest.Create 正在同步处理并且可以获得一些时间(dns 查找、代理设置等),如果我发出很多请求,他们可以简单地填充我的所有线程(UI 线程)来创建 WebRequest。但是我尝试创建指向直接 IP 地址的请求 (WebRequest.Create(String.Format("https://10.10.10.1/page{0}", iLocal)) - 没有任何改变,而且我正在设置代理(因此不需要自动检测代理),所以我不明白为什么创建需要这么多时间(是创建问题还是其他问题?)。

请有人指出我做错了什么?我迷失在所有ServicePointManager 设置中(我尝试的所有方法都没有帮助)。 .Net 可以处理这种类型的任务吗?或者我可能需要使用 nodejs 来获得最佳性能?

P.S:代理的集合不是那么大(50-100 个不同的代理)。

【问题讨论】:

    标签: c# performance asynchronous proxy httpwebrequest


    【解决方案1】:

    Back to (Parallel) Basics: Don't Block Your Threads, Make Async I/O Work For You

    例子:

    Parallel.For(0, 10, delegate(int i) {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
            new Uri("http://www.mysi.com"));
    
        string dataToSend = "Data";
        byte[] buffer = System.Text.Encoding.GetEncoding(1252).
            GetBytes(dataToSend);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = buffer.Length;
    
        request.Host = "www.mysite.com";
    
        Stream requestStream = request.GetRequestStream();
        requestStream.Write(buffer, 0, buffer.Length);
        requestStream.Close();
    
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    });
    

    Send multiple WebRequest in Parallel.For

    【讨论】:

    • 你能解释一下你对这篇文章的意思吗?谢谢。
    • 如果你使用 async/await 我们需要使用 Parallel 而不是 Task.Run
    • 嗯。 Parallel 和 Task.Run 之间有什么区别吗?我不确定,但并行也适用于任务。它对我的情况有何帮助?谢谢。
    • 有趣。你能指出我在哪里可以阅读关于 Task.Run 和 async/await 不能正常工作的信息吗?这对我来说真的很令人惊讶。谢谢。
    • 您也可以尝试使用 Task.WhenAll 代替 Task.Run msdn.microsoft.com/en-us/library/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-27
    • 2011-12-01
    相关资源
    最近更新 更多