C#加速webclient下载

C# speed up webclient download

如何通过循环url加快下载html网站源代码的速度?

我正在使用此代码下载,但速度很慢。 (每个 url 的平均下载时间约为 5 秒)

using (WebClient client = new WebClient())
{
    for (int i = 0; i <= 20; i++)
    {
        var source_code = client.DownloadString(url[i]);
    }
}

如果您要从 20 个不同的网址中抓取数据,并且如果这些调用中 none 依赖于其他调用,那么您为什么要循环执行此操作?为什么不使用 20 个不同的 Web 客户端制作 20 个不同的 asynchronous calls?然后,当它们全部完成后,您可以将结果拼接在一起。

类似于:

// Start the HandleFile method.
Task<string> task1 = ScrapeUrl(url1);
Task<string> task2 = ScrapeUrl(url2);
Task<string> task3 = ScrapeUrl(url3);
...


// Control returns here before scraping is done.

Console.WriteLine("Please wait patiently...");

// Wait for the scraping tasks to complete.
// ... Display its results.
string result1 = await task1;
string result2 = await task2;
string result3 = await task3;
...

您显然无法加快每个下载的速度,但您可以并行下载多个 url 的内容。有很多方法可以做到这一点,这里是一种使用 Parallel.ForEach:

var urls = new List<string>() { "http://www.google.com", "http://www.whosebug.com" };
var results = new ConcurrentDictionary<string, string>();

Parallel.ForEach(urls, url =>
{
    using (var webClient = new WebClient())
    {
        results[url] = webClient.DownloadString(url);
    }
});

结果以 URL 作为关键字存储在 ConcurrentDictionary 中,因此在循环完成后您可以提取下载的代码。您可能需要添加一些代码来引入错误处理,并且可能需要添加一些合理的超时,但我希望这会给您一个想法。

至 post 另一种选择,就像到目前为止的答案一样,这是一个仅在 async 方法中使用 HttpClient 的一个实例的版本,您基本上可以分拆 20作业并从这些作业中的 URL 中获取 HTML 内容,一旦作业开始,您就可以等待它们全部完成。

我 post 将此与其他答案一起编辑的原因是,如果您使用 HTTP 客户端,则每个 URL 不需要多个客户端实例。

private async Task GetAuctionData()
{
    List<Task> tasks = new List<Task>();
    using (var client = new HttpClient())
    {
        for (int i = 0; i < dataGridView1.Rows.Count; i++)
        {
            var downloadTask = Task.Run(() =>
                {
                    // Perform work here on HttpClient
                });
            tasks.Add(downloadTask);
        }

        await Task.WhenAll(tasks);
    }
}