2014-04-03 3 views
0

나는 일정한 수의 작업/스레드 (프로세서 수에 가깝다)를 병렬로 처리하고자하는 소스 IEnumerable<T>을 가지고있다. 소스의 다음 항목을 처리하고 모든 요소가 반복 될 때까지 처리합니다.일정한 수의 작업/스레드와 병렬로 IEnumerable 사용하기

  • Parallel.For은 요소 수를 알 수 없으므로 후보가 아닙니다.
  • Parallel.ForEach은 후보가 아니기 때문에 MaxDegreeOfParallelism을 지정하는 경우에도 많은 작업이 생성되므로이 매개 변수는 동시에 실행되는 최대 작업 수만 생성되지만 생성되는 작업 수는 보장하지 않습니다.
  • 각 태스크는 소스가 끝날 때까지 통과한다는 알림을 받아야하므로 일부 랩핑 로직을 실행할 수 있습니다.
  • 소스 목록의 요소는 메모리에 보관할 수 없지만 계속 처리하고 폐기해야합니다.

생산자가 단일 스레드 일 수 있고 IEnumerable이 완료되면 더 이상 요소가 추가되지 않는다는 단순화와 함께 생산자/소비자 문제가 발생합니다.

이 문제에 대한 해결책은 TPL 사용과 어떻게 비슷합니까? 나 자신의 공유 가능한 thread-safe IEnumerable을 구현해야합니까, 아니면 프레임 워크가 무언가를 제공합니까?

EDIT :이 시도는 Parallel.ForEach이고 내게는 MaxDegreeOfParallelism으로 지정되어 TPL이 많은 작업을 만들지 못하게합니다.

int nbTasks = 0; 
Parallel.ForEach(positions, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, 
    () => { return new List<IPositionData>(); }, 
    (position, loop, list) => 
    { 
     Thread.Sleep(1); 
     list.Add(position); 
     return list; 
    }, 
    list => Interlocked.Add(ref nbTasks, 1)); 
Trace.WriteLine(string.Format("Tasks: {0}", nbTasks)); 

코멘트 : positions 내 소스 IEnumerable<IPositionData>입니다. 난 그냥 이걸 실행하고 예를 들어, nbTasks는 64 (내 4 코어에 예상 4가 아닙니다)입니다.

답변

6

ParallelOptions 개체를 예상하고 MaxDegreeOfParallelism 속성을 설정하는 오버로드를 사용하여 Parallel.ForEach의 작업 수를 제한 할 수 있습니다.

+0

내가 성공하지 정확히이 일을 시도했습니다. 예를 들어 MaxDegreeOfParallelism을 4로 지정해도 훨씬 많은 작업이 4보다 많이 생성되고 있습니다. 이것은 CPU에 대한 경계가 아닌 초기화 때문입니다. 나는 이것을 반영하기 위해 나의 질문을 편집했다. – Dejan

+0

@Dejan 약간의 코드를 보여 주시겠습니까? 난 그냥 간단한 예제를 시도하고 내 경우에는 'MaxDegreeOfParallelism' 제대로 작동하는지 확인할 수 있습니다. – decPL

+0

예, 여기 있습니다. – Dejan

0

당신은 Parallel.ForEach에서 작업의 수를 제한 할 수 있습니다 :

in maxNumberOfTasks = 4; 
    Parallel.ForEach(collection, new ParallelOptions { MaxDegreeOfParallelism = maxNumberOfTasks}, 
       i => { 
         //Your action here 
        });