2013-05-07 2 views
18

Parallel.Foreach 루프에서 청크 분할을 사용하는 방법을 아는 사람이 있습니까? 기본적으로 범위 분할이 있다고 생각합니다. 배열로 작업 할 때 사용자 정의 분할자를 만들고로드 균형 조정을 true로 설정할 수 있기 때문에 간단 해 보입니다.Parallel.Foreach에서 팩 ​​분할 IEnumerable

IEnumerable의 요소 수는 런타임까지 알 수 없으므로 작동하도록 청크 분할을 얻는 좋은 방법을 찾을 수 없습니다.

도움을 주시면 감사하겠습니다.

감사합니다.

각 개체에서 수행하려고하는 작업은 수행하는 데 상당한 시간이 걸립니다. 결국 나는 마지막 스레드가 작업을 마칠 때까지 보통 몇 시간을 기다린다. 내가 달성하려고하는 것은 각 스레드에 항목을 미리 할당하는 대신 병렬 루프 요청 청크를하는 것입니다.

+0

왜 관심이 있습니까? –

+0

청크의 수 또는 청크 당 크기로 청크합니다. – SimpleVar

+0

IEnumerable을 가지고 있습니까? 아니면 인덱서를 구현하는 무언가를 가지고 있습니까? (그래서'obj [i]'를 할 수 있습니까?) 색인을 전달할 수 있다면 해결책이 있습니다. –

답변

19

당신을 IEnumerable 정말이 인덱서 당신이 작성해야합니다 그것을 할 수없는 경우 (당신이 항목을 얻을 수 obj[1]을 할 수있는 예) 당신은 그러나 다음

var rangePartitioner = Partitioner.Create(0, source.Length); 
    Parallel.ForEach(rangePartitioner, (range, loopState) => 
    { 
     // Loop over each range element without a delegate invocation. 
     for (int i = range.Item1; i < range.Item2; i++) 
     { 
      var item = source[i] 
      //Do work on item 
     } 
    }); 

을 할 수 있었다 것이었다 경우 System.Collections.Concurrent.Partitioner<TSource>에서 파생 된 새 클래스를 만들어 사용자 정의 파 티셔 터를 만듭니다. 그 주제가 너무 넓어서 SO 대답을 다루지는 않지만 시작하려면 this guide on the MSDN을 살펴보십시오.

UPDATE : 그들은 데이터를 버퍼링하지 않는 Partitioner.Create 과부하를 추가 .NET 4.5으로, 당신은을받지 않습니다이와 함께 1의 범위를 최대 크기로 사용자 정의 파티션 프로그램을 만드는 같은 효과가 있습니다 한 줄의 느린 항목이 연속적으로 불행하다면 대기열에 들어간 작업이 하나씩 있습니다.

var partitoner = Partitioner.Create(source, EnumerablePartitionerOptions.NoBuffering); 
Parallel.ForEach(partitoner, item => 
{ 
    //Do work 
}