2014-11-20 4 views
0

나는 범위 오류에서 인덱스를 얻고있다Paraller의 foreach 문은

var list=new list<PriceDetails>(); 
Parallel.ForEach(productResults.Items, productPrices => 
{ 
    var priceDetail=new PriceDetails { price=productPrices.prices.firstordefault();} 
    list.add(priceDetail); 
} 

문제 사용하여 동시 위의 해결 예를 제공하세요?

+0

이것은 의미가 없습니다. 가격이 항상 목록의 첫 번째 가격 인 가격 세부 정보 목록을 만듭니다. 어쩌면 성취하고자하는 것을 설명 할 수 있습니까? – nvoigt

+0

샘플 코드 나는 1000 개의 가격에서 가격을 받고 루프를 작성하고 가격 정보 객체를 할당한다. – mrl

+1

@nvoigt 그는 각 제품의 첫 번째 가격을 * 목록에 추가한다. 하지만 매번 다른 제품의 가격입니다. – Servy

답변

2

문제는 List.Add(이므로 동시에 사용하는 여러 스레드를 지원하지 않습니다. 더 나은 솔루션은 AsParallel()ToList() 함수를 통해 List<PriceDetails>을 생성하기 위해 PLinq를 사용하는 것입니다.

var list = productResults.Items 
       .AsParallel() 
       .Select(productPrices => new PriceDetails { price = productPrices.prices.firstordefault()}) 
       .ToList(); 

이 코드는 소스 모음을 병렬로 처리하고 새 클래스를 빌드 한 다음 모든 항목을 목록에 결합하여 변수에 할당합니다.

그러나 나는 이것을 시험해 보지 않고도 AsParallel() 병렬 처리는 간접 비용이 들며 새로운 클래스를 만드는 것은 일반적으로 저렴한 opration입니다. AsParallel() 수정자가 없으면 코드가 더 빠르게 실행될 수 있습니다.

+0

_ AsParallel() 수식어를 사용하지 않고 코드가 더 빨리 실행되는 경우가 있습니다. 몇 가지 사항을 말씀 드리겠습니다. 병렬 코드를 __not__로 사용하는 좋은 예입니다. – TaW

+0

@TaW (for 루프)를 사용하여 코드를 테스트했으며 1000 개의 가격에 대해 AsParallel을 사용하고 AsParallel은 일반 루프보다 약 100 ms 빠르고 코드가 잘못됨 – mrl

7

List<T>은 동시에 여러 스레드에서 액세스하지 않는다는 가정하에 설계되었습니다. 여러 스레드에서 병렬로 조작하는 것은 안전하지 않습니다. System.Collections.Concurrent과 같은 을 지원하는 다른 유형의 데이터 구조를 사용해야합니다. 음, 처음부터 병렬로 처리 할 수는 없습니다. 처음에는이 작업을 병렬화 할 이유가 없습니다.

+0

동시 목록을 의미합니까? C#에 동시 목록이 있습니까? – mrl

+0

동시 목록이 없습니다. 앞에서 말했듯이이 작업을 병렬 처리하면 안됩니다. 그래도 순차적으로 수행해야하지만, 어쨌든 그렇게하고 싶다면 사용 가능한 컬렉션을 살펴보고 필요에 맞는 것을 확인해야합니다. – Servy

+0

이렇게하려면 [ConcurrentBag] (http://msdn.microsoft.com/en-us/library/dd381779(v=vs.110) .aspx)를 사용하는 것이 좋습니다. populate가 끝나면 필요한 경우 목록으로 다시 변환 할 수있는 ToList 메서드가 있습니다. – AWinkle