나는 일정한 수의 작업/스레드 (프로세서 수에 가깝다)를 병렬로 처리하고자하는 소스 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가 아닙니다)입니다.
내가 성공하지 정확히이 일을 시도했습니다. 예를 들어 MaxDegreeOfParallelism을 4로 지정해도 훨씬 많은 작업이 4보다 많이 생성되고 있습니다. 이것은 CPU에 대한 경계가 아닌 초기화 때문입니다. 나는 이것을 반영하기 위해 나의 질문을 편집했다. – Dejan
@Dejan 약간의 코드를 보여 주시겠습니까? 난 그냥 간단한 예제를 시도하고 내 경우에는 'MaxDegreeOfParallelism' 제대로 작동하는지 확인할 수 있습니다. – decPL
예, 여기 있습니다. – Dejan