如何发送多个 Web 请求并尽快处理它们



我正在开发一个 C# winforms 应用程序,我有大约 84 个 url,我想使用 html 敏捷包解析它们

对于 84 条记录,使用以下代码完成作业需要 150 秒。

我想知道我有什么选择可以让它运行得更快? 任何帮助都非常感谢!

以下是我完成这项工作的代码结构

public class URL_DATA
{
    public string URL { get; set; }
    public HtmlDocument doc  { get; set; }
}
then I call the below function to do the job
 public async Task ProcessUrls(string cookie)
 {
                var tsk = new List<Task>();
                //UrlsToProcess is List<URL_DATA>
                UrlsToProcess.ForEach(async data =>
                {
                    tsk.Add(Task.Run(async () => 
                    {
                      var htmToParse =  await ScrapUtils.GetAgilityDocby(cookie, data.URL);
                        var htmlDoc = new HtmlDocument();
                        htmlDoc.LoadHtml(htmToParse);
                        data.doc = htmlDoc;
                    }));
                });
                await Task.WhenAll(tsk).ConfigureAwait(false);    
   }

最后是我用来获取请求字符串的方法。

 public static async Task<string> GetAgilityDocby(string cookie, string url)
        {
            using (var wc = new WebClient())
            {
                wc.Proxy = null;// WebRequest.DefaultWebProxy;// GlobalProxySelection.GetEmptyWebProxy();
                wc.Headers.Add(HttpRequestHeader.Cookie, cookie);
                wc.Headers.Add(HttpRequestHeader.UserAgent,
                    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36");
                wc.Encoding = Encoding.UTF8;
                test++;
                return await  wc.DownloadStringTaskAsync(url).ConfigureAwait(false);
            }
        }

您正在使用具有异步 lambda 的ForEach。我怀疑它会使您的代码按顺序运行而不是并行运行,因为每次下一次迭代都会等待。

所以你可以做些什么来确定这一点:

  1. 检查一个 URL 的操作的最长时间,该时间应该大约是整个事情应该有多快(如果您有足够的带宽、内存和 CPU(。
  2. 验证操作是否确实并行运行。例如,通过将计数器输出到控制台。它不应该是连续的,看起来足够随机

您可以将任务创建代码更改为此代码,例如尝试:

var allTasks = myUrls.Select(url => Task.Run(() => {yourCode})
Task.WhenAll(allTasks);

尝试将最小运行线程数增加

ThreadPool.SetMinThreads(84,84);

这应该会加快速度。

至于 Ilya 指出的任务创建,我会评论您完全省略 Task.Run/AwaitAll 部分并使用并行机制,该机制正是针对此类问题开发的:

Parallel.ForEach(UrlsToProcess, data =>
{
    var htmToParse =  ScrapUtils.GetAgilityDocby(cookie, data.URL);
    var htmlDoc = new HtmlDocument();
    htmlDoc.LoadHtml(htmToParse);
    data.doc = htmlDoc;
});

相关内容

  • 没有找到相关文章

最新更新