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

时间:2019-04-11 09:29:11

标签: c# parallel-processing task webclient

我正在使用C#winforms应用程序,我想使用html敏捷包解析大约84个网址

对于84条记录,使用下面的代码需要150秒才能完成工作。

我想知道我需要什么选择来使其运行更快?任何帮助深表感谢!

以下是我要做的代码结构

matrixWorld

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

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);    
   }

2 个答案:

答案 0 :(得分:0)

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

ThreadPool.SetMinThreads(84,84);

这应该可以大大加快速度。

对于Ilya指出的Task-Creation,我建议您完全省略Task.Run / AwaitAll部分,并使用为解决此类问题而开发的Parallel机制:

Parallel.ForEach(UrlsToProcess, data =>
{
    var htmToParse =  ScrapUtils.GetAgilityDocby(cookie, data.URL);

    var htmlDoc = new HtmlDocument();
    htmlDoc.LoadHtml(htmToParse);
    data.doc = htmlDoc;
});

答案 1 :(得分:0)

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

那么您可以做什么来确定这一点:

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

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

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