2017-05-16 3 views
0

최근까지, 나는 인덱서를 통해 List<T>의 요소를 설정하면 다음과 같은 상황에서 안전 스레드가 있다는 가정하에 있었다. 배열C# 목록 <T> 인덱서 스레드 안전

// Assumes destination.Count >= source.Count 
static void Function<T,U>(List<T> source, Func<T,U> converter, List<U> destination) 
{ 
    Parallel.ForEach(Partitioner.Create(0, source.Count), range => 
    { 
     for(int i = range.Item1; i < range.Item2; i++) 
     { 
      destination[i] = converter(source[i]); 
     } 
    }); 
} 

List<T> 저장 소자 이후 내부적 리사이징 필요로하지 않아야 인덱스 한 설정이 믿음 합리적인 도약 같았다. 그러나 .NET 코어에서 implementationList<T> 인 것을 보면 인덱서의 설정자가 일부 내부 상태를 수정 한 것처럼 보입니다 (아래 참조).

// Sets or Gets the element at the given index. 
public T this[int index] 
{ 
    get 
    { 
     // Following trick can reduce the range check by one 
     if ((uint)index >= (uint)_size) 
     { 
      ThrowHelper.ThrowArgumentOutOfRange_IndexException(); 
     } 
     Contract.EndContractBlock(); 
     return _items[index]; 
    } 

    set 
    { 
     if ((uint)index >= (uint)_size) 
     { 
      ThrowHelper.ThrowArgumentOutOfRange_IndexException(); 
     } 
     Contract.EndContractBlock(); 
     _items[index] = value; 
     _version++; 
    } 
} 

그래서 나는 List<T>는 스레드로부터 안전하지 않습니다 것을 각 스레드는 컬렉션의 고유 한 부분에서 요소를 설정/얻고 경우에도 가정해야합니까?

+1

([당신이 부르는 일이 무엇입니까? "스레드로부터 안전합니다"] https://blogs.msdn.microsoft.com/ericlippert/2009/10/19/what-is-this-thing-you-call-thread -안전한/). 가장 먼저해야 할 일은 안전이 필요한 것을 파악하는 것입니다. 보고있는 코드에 관해서는 스레드로부터 안전하다고는 말할 수 없습니다. 그리고 실제로는 thread-safe로서 문서화되지 않은 것을 가정해서는 안됩니다. 그러나,'_version' 필드는 당신이 신경 쓸 필요가없는 구현 세부 사항에 사용됩니다. 안전하지 못하다는 사실이 당신에게 중요하지 않을 수도 있습니다. –

+1

당신이 스레드 안전을 원하는 경우에, 당신이있어 비록 [스레드 안전 컬렉션] (https://msdn.microsoft.com/en-us/library/dd997305 (V = vs.110)에서 .aspx) – Timo

+0

를 살펴 실제로 이것을 요구하지는 않지만 병렬 루프 내에서 상태를 수정하지 않는 것이 좋습니다. 상황이'converter'가 장기 실행 연산 인 경우에는'Parallel'을 사용하여 결과를 계산 한 다음 하나의 스레드로 결과를 할당하는 것이 가장 좋습니다. 이것을보십시오 :'static List Function (소스 코드 소스, Func 변환기) {return source.AsParallel(). (변환기 =) 변환기를 선택하십시오. }' – Enigmativity

답변

4

가 여기 읽게

https://msdn.microsoft.com/en-us/library/6sh2ey19.aspx#Anchor_10

귀하의 질문에 대답하기 위해, 더는 - 문서에 따라, 스레드 안전이 보장되지 아니에요.

현재 구현이 스레드 안전성 (어쨌든)이 아닌 것으로 나타난다하더라도, 여전히 그 가정을하는 것은 나쁜 생각입니다. 문서에서는 스레드로부터 안전하지 않다고 명시 적으로 말하고 있기 때문에 향후 버전에서는 더 이상 스레드로부터 안전하지 않게 기존의 구현을 법적으로 변경하고 이전에 의존했던 가정을 깨뜨릴 수 있습니다.