2014-03-06 1 views
4

제가 일하는 회사는 수백 개의 매우 역동적 인 웹 사이트를 운영합니다. 그것은 검색 엔진을 구축하기로 결정하고 나는 스크레이퍼를 작성하는 임무를 부여 받았다. 사이트 중 일부는 오래된 하드웨어에서 실행되며 많은 처벌을받을 수 없으며 다른 사이트에서는 대량의 동시 사용자를 처리 할 수 ​​있습니다..NET에서 병렬 스크래핑

나는, 내가 스레드, 뮤텍스는 세마포어 등이 작업을 수행하는 데 사용할 수있는 알고 C.

사이트에 대한 사이트 A, 사이트 B 2 1에 대한 사용 5 병렬 요청을 말할 수 있어야합니다 그러나 그것은 매우 복잡 할 것입니다. TPL과 같은 상위 수준의 프레임 워크가/async, TPL Dataflow가 더 간단한 방식으로이 앱을 수행 할만큼 강력하다는 것을 기다리고 있습니까?

답변

10

난 당신이 간단한 조절을 위해 SemaphoreSlim으로, Task.WhenAllHttpClient를 사용하는 것이 좋습니다 :

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을 설정할 수 있습니다.

1

TPL Dataflowasync-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; 
}