Webclient.DownloadStringAsync Загрузка нескольких URL-адресов слишком медленная

Я пытаюсь загрузить файлы в то же время.

-Скачать строку по основной ссылке

-Возьмите из него подссылки

-Загружайте субссылки одновременно (590 ~ субссылок для загрузки) Как дерево.

    static async Task Direct()
    {
        WebClient wc2 = new WebClient() { UseDefaultCredentials = true, Encoding = Encoding.GetEncoding(1251) };
        HtmlDocument hd = new HtmlDocument();
        wc2.Proxy.Credentials = CredentialCache.DefaultCredentials;
        hd.LoadHtml(wc2.DownloadString(link));
        foreach (var item in hd.DocumentNode.SelectNodes(xpath).Select(x => x.GetAttributeValue("href", "")))
        {
            Task.Run(() =>
                {
                    using (WebClient wc = new WebClient() { UseDefaultCredentials = true, Encoding = Encoding.GetEncoding(1251) })
                    {
                        wc.DownloadStringCompleted += Over;
                        wc.Proxy.Credentials = CredentialCache.DefaultCredentials;
                        wc.DownloadStringAsync(new Uri(item));
                    }
                });
        }
        Console.Title = "ready";
    }
    static Stopwatch sw = new Stopwatch();
    static void Over(object sender, DownloadStringCompletedEventArgs e)
    {
        Task.Run(()=>overTask((sender as WebClient)));
    }
    static async Task overTask(WebClient sender)
    {
        if (sw.IsRunning)
        {
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            sw.Reset();
        }
        sw.Start();
        sender.Dispose();
    }

1-Этот код у меня есть, он загружает субссылки, но не одновременно, медленнее, чем он. Требуется запрос DownloadStringAsync, и я надеюсь, что максимум 20 секунд для всех строк, но мой большой секундомер показывает мин. 35 сек.

2-Это 1000 мс, я ожидаю, что макс. 20 мс. потому что они должны начаться в одно и то же время, между ними нет большой разницы. Тот же сайт, разные страницы.

Я делаю несколько изменений в первом коде. Есть некоторые улучшения, но все же они медленнее, чем я исключал. Результат.

как говорит @Liam, я пытался сделать это через поток.

static async Task Direct()
    {
        WebClient wc2 = new WebClient() { UseDefaultCredentials = true, Encoding = Encoding.GetEncoding(1251) };
        HtmlDocument hd = new HtmlDocument();
        wc2.Proxy.Credentials = CredentialCache.DefaultCredentials;
        hd.LoadHtml(wc2.DownloadString(link));
        foreach (var item in hd.DocumentNode.SelectNodes(xpath).Select(x => x.GetAttributeValue("href", "")))
        {
            /* Task.Run(() =>
                {
                    using (WebClient wc = new WebClient() { UseDefaultCredentials = true, Encoding = Encoding.GetEncoding(1251) })
                    {
                        wc.DownloadStringCompleted += Over;
                        wc.Proxy.Credentials = CredentialCache.DefaultCredentials;
                        wc.DownloadStringAsync(new Uri(item));
                    }
                });*/

            new Thread(() =>
            {
                using (WebClient wc = new WebClient() { UseDefaultCredentials = true, Encoding = Encoding.GetEncoding(1251) })
                {
                    wc.DownloadStringCompleted += Over;
                    wc.Proxy.Credentials = CredentialCache.DefaultCredentials;
                    wc.DownloadStringAsync(new Uri(item));
                }
            }).Start();
        }
        Console.Title = "ready";
    }
    static Stopwatch sw = new Stopwatch();
    static void Over(object sender, DownloadStringCompletedEventArgs e)
    {
        new Thread(() =>
        {
            if (sw.IsRunning)
            {
                sw.Stop();
                Console.WriteLine(sw.ElapsedMilliseconds);
                sw.Reset();
            }
            sw.Start();
        }).Start();

выходная мс (мс между двумя загрузками) здесь

РЕДАКТИРОВАТЬ: Ребята, цикл foreach должен запускать их через небольшие различия. На этот вопрос нет ответа. Я сказал: «Если задачи запускаются в одно и то же время (по крайней мере, между ними небольшие различия) и они загружают вещи, которые имеют одинаковую длину строки (изменено 20-30 символов), то почему разница между ними слишком велика? Это зависит от сайта, можно ли сделать быстрее?


person GBursali    schedule 21.04.2017    source источник
comment
Помещение асинхронного вызова в Task несколько побеждает объект асинхронного вызова. Почему бы вам не запустить их, собрать Tasks, возвращенные в массив, а затем await на них?   -  person Liam    schedule 21.04.2017
comment
Возможный дубликат Выполнение нескольких асинхронных задач и ожидание их все завершить   -  person Liam    schedule 21.04.2017
comment
Я также хотел бы прочитать Использование секундомера с асинхронными методами   -  person Liam    schedule 21.04.2017
comment
ServicePointManager ограничивает количество одновременных подключений к одному компьютеру, поэтому вы можете изучить возможность увеличения максимального количества подключений.   -  person Crowcoder    schedule 21.04.2017
comment
@Liam Я создаю список задач и добавляю в него каждую задачу. Затем я попытался использовать метод waitall, программа зависла на этой строке.   -  person GBursali    schedule 21.04.2017
comment
Да, это и есть асинхронность. Ты говоришь ему подождать (WaitAll()). Подсказки в названии :)   -  person Liam    schedule 21.04.2017
comment
Если вы хотите огонь и забыли не использовать async, используйте для этого потоки. Опять же, см. здесь запустить и забыть с асинхронным и «старым» асинхронный делегат”. Кстати, я бы предположил, что вы делаете то, что делают все, асинхронный! = потоки. async паркует потоки, потоки порождают новые потоки. У них разные варианты использования   -  person Liam    schedule 21.04.2017