2012-08-27 3 views
1

동시에 처리해야하는 파일 목록이 있습니다. ParallelQuery 클래스의 ForAll 확장 메서드를 사용하려고했습니다. 나는 순서대로 처리 할 파일이 없으므로 ForAll을 사용했습니다.ParallelQuery.ForAll의 ID 증가 방법

List<FileInfo> files = GetFilesToProcess(); 

files.AsParallel().ForAll(f => { // Process file here }); 

그것은 잘 작동하지만 지금은 파일의 각과를 ForEach에 AsParallel.ForAll을 변경하지 않고 그것을 할 어떻게 확실하지에 대한 고유 한 정수 ID를 생성해야합니다

여기 내 예제 코드입니다 .

내가 연동 된 것처럼 어딘가에 읽었지만 여전히 문제가있을 것입니다.

희망은 나에게 아이디어를 줄 수 있습니다.

감사합니다.

답변

2

당신은 ID를 생성하는 Interlocked.Increment를 사용하거나 그냥 직접 인덱스를 사용할 수 있습니다 : 당신이 Interlocked.Increment를 사용하려면

List<FileInfo> files = GetFilesToProcess(); 

files.AsParallel().Select((f, i) => new {File=f, ID=i}) 
    .ForAll(fp => 
      { 
       FileInfo file = fp.File; 
       int id = fp.ID; // ID is the index in the list 

       // Process file here 
      }); 

, 당신이 할 수 있습니다 :

List<FileInfo> files = GetFilesToProcess(); 
int globalId = -1; 

files.AsParallel().ForAll(f => 
         { 
           // Process file here 
           int id = Interlocked.Increment(ref globalId); 
           // use ID 
         }); 

말했다되고 그건 전체 목표가 컬렉션에서 "작업"을 수행하는 것이라면 대신 Parallel.For 또는 Parallel.ForEach로 작성하는 것이 좋습니다.

List<FileInfo> files = GetFilesToProcess(); 
Parallel.For(0, files.Count, i => 
{ 
    var file = files[i]; 
    // Use i and file as needed 
}); 
+0

안녕하세요, 귀하의 제안 된 솔루션과 답장을 보내 주셔서 감사합니다. Parallel For/ForEach를 사용하면 ForAll에서와 같이 병렬로 실행된다는 것을 명확히하고 싶습니다. 미안합니다. 당신이 바보 같은 질문이라고 생각한다면. 그냥 확인하고 싶습니다. – lionheart

+0

@lionheart 예 - 두 가지 접근 방식이 있습니다. 일반적으로 어떤 형태의 필터링 연산 ('.Where')이나 맵 연산 ('.Select')을 수행하고 있다면 PLINQ ('.AsParallel()')을 사용할 것입니다. '.ForAll()'메소드는 "쿼리"의 결과에 대한 작업을 할 때 단순화하기 위해 도입되었습니다. 귀하의 목표가 단지 "병렬로 작업을 수행"하는 것이라면, Parallel.For와 Parallel.ForEach가 훨씬 더 적합합니다. 이유에 대해 좋은 논거를하려면 http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx –

+0

을 읽어보십시오. 감사 리드! – lionheart

0

당신이 정말로해야하는 경우에, 당신은 당신이 Interlocked.Increment을 통해 처리 int을 할 수 : 당신은 부작용을 생성하기위한 목적으로 LINQ 스타일의 구문을 사용하지 않는 이것은 훨씬 더 분명하다.

소스의 색인을 사용하는 것이 더 나은 방법입니다. 이는 이미 파티션 작성자가 사용할 수있는 정보이므로 Interlocked과 같은 가벼운 공유에서도 여전히 공유됩니다.

또는 건너 뛸 수 있으며 일종의 UUID를 사용할 수 있습니다. 이 경우에는 그만한 가치가 있기에 무거워 질 것입니다. (색인을 멋지고 가볍게 만드십시오). "병렬 작업간에 공유하지 않고이 작업을 수행 할 수 있습니까?"라는 질문에 대해 언급합니다. 나중에 해산 되더라도 항상 고려되어야한다.