Лучший способ загрузки html контента с нескольких страниц [c #] - PullRequest
2 голосов
/ 01 августа 2020

Я пишу программу очистки веб-страниц, и здесь у меня есть ситуация, когда у меня есть 10 ссылок на одной странице, и для каждой ссылки мне нужно загрузить html текст, чтобы удалить с них данные, перейти на следующую страницу и повторить все обработать. Когда я делаю это синхронно для одной ссылки, для загрузки html текста требовалось 5-10 сек c (это медленно, когда я пытаюсь открыть страницу в браузере). Поэтому я искал асинхронный способ реализовать это, и для 10 ссылок потребовалось 5-10 сек c, чтобы загрузить html текст. Мне нужно l oop через 100 страниц, и для обработки всех данных потребовалось 30 минут.

У меня нет большого опыта работы с задачами в C#, поэтому я сделал этот код, и он работает, но я не уверен, что это хорошо или есть лучшее решение?

class Program
{
    public static List<Task> tasks = new List<Tasks>();
    public static List<Data> webData = new List<Data>();

    public static async Task<string> GetHtmlText(string link)
    {
        using (HttpClient client = new HttpClient())
        {
            return await client.GetStringAsync(link);
        }
    }

    public static void Main(string[] args)
    {

        for(int i = 0; i < 100; i++)
        {
            List<string> links = GetLinksFromPage(i); // returns 10 links from page //replaced with edit solution >>>
            
            foreach (var link in links)
            {
                Task<string> task= Task.Run(() => GetHtmlText(link));
                TaskList.Add(task);
            }

            Task.WaitAll(TaskList.ToArray()); // replaced with edit solution <<<

            foreach(Task<string> task in TaskList)
            {
                string html = task.Result;
                Data data = GetDataFromHtml(html);
                webData.Add(data);
            }
            ...
        }
}

EDIT: Это сделало мой день, установив DefaultConnectionLimit на 50 DefaultConnectionLimit

ServicePointManager.DefaultConnectionLimit = 50

var concurrentBag = new ConcurrentBag<string>();

var t = linksFromPage.Select(async link =>
        {
             var response = await GetLinkStringTaskAsync(link);
             concurrentBag.Add(response);
         });

await Task.WhenAll(t);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...