Параллельный парсинг в .NET

Компания, в которой я работаю, управляет несколькими сотнями очень динамичных веб-сайтов. Было принято решение построить поисковую систему, а мне поручили написать парсер. Некоторые из сайтов работают на старом оборудовании и не выдерживают больших нагрузок, в то время как другие могут обрабатывать огромное количество одновременных пользователей.

Мне нужно иметь возможность использовать 5 параллельных запросов для сайта A, 2 для сайта B и 1 для сайта C.

Я знаю, что для этого можно использовать потоки, мьютексы, семафоры и т. д., но это будет довольно сложно. Достаточно ли мощные фреймворки более высокого уровня, такие как TPL, await/async, TPL Dataflow, чтобы упростить это приложение?


person Bob    schedule 06.03.2014    source источник


Ответы (2)


Я рекомендую вам использовать HttpClient с Task.WhenAll, с SemaphoreSlim для простого дросселирования:

private SemaphoreSlim _mutex = new SemaphoreSlim(5);
private HttpClient _client = new HttpClient();
private async Task<string> DownloadStringAsync(string url)
{
  await _mutex.TakeAsync();
  try
  {
    return await _client.GetStringAsync(url);
  }
  finally
  {
    _mutex.Release();
  }
}

IEnumerable<string> urls = ...;
var data = await Task.WhenAll(urls.Select(url => DownloadStringAsync(url));

В качестве альтернативы вы можете использовать поток данных TPL и установить MaxDegreeOfParallelism для регулирования.

person Stephen Cleary    schedule 06.03.2014

TPL Dataflow и async-await действительно мощные и достаточно простые, чтобы иметь возможность делать то, что вам нужно:

async Task<IEnumerable<string>> GetAllStringsAsync(IEnumerable<string> urls)
{
    var client = new HttpClient();
    var bag = new ConcurrentBag<string>();
    var block = new ActionBlock<string>(
        async url => bag.Add(await client.GetStringAsync(url)),
        new ExecutionDataflowBlockOptions {MaxDegreeOfParallelism = 5});
    foreach (var url in urls)
    {
        block.Post(url);
    }
    block.Complete();
    await block.Completion;
    return bag;
}
person i3arnon    schedule 06.09.2014