obj.Coll
은 열거하는 동안 변경됩니다. 현재의 thread에 의해 변경되지 않는 경우는, 다른 thread에 의해 변경 될 가능성이 있습니다. 현재 스레드가 컬렉션을 변경하면 기본적으로이 문제를 해결하는 두 가지 방법이 있습니다. 컬렉션 복사본을 만들고 복사본을 열거 할 수 있습니다. 컬렉션을 열거 할 때까지 변경 내용을 연기 할 수 있습니다.
그러나 컬렉션이 다른 스레드에 의해 변경되면 스레드 안전 모드 (여기뿐만 아니라 모든 곳)에서 컬렉션에 액세스해야합니다.
편집 Kieren 존스톤에 대한는 :
나는 List<T>.ToArray()
는 스레드로부터 안전하지 않습니다 것을 보여주기 위해 짧은 코드를 썼다.
var list = new List<int>();
Task.Factory.StartNew(() => {
for (int i = 0; i < 1000000; ++i) {
list.Clear();
// Add values from 1 to 9
for (int j = 1; j < 10; ++j) {
list.Add(j);
}
}
Console.WriteLine("Thread Exit: list.Add()");
});
Task.Factory.StartNew(() => {
for (int i = 0; i < 100; ++i) {
var array = list.ToArray();
if (array.Length > 0) {
Console.WriteLine("ToArray(): {0}", string.Join(", ", array));
}
}
Console.WriteLine("Thread Exit: list.ToArray()");
});
다음은 출력 코드입니다. 나는 그것이 나의 주장을 증명했다고 생각한다. 발췌 문장에는 15 개의 행이 포함되어 있으며 그 중 9 개의 행에는 잘못된 데이터가 들어 있습니다. 우리가 list.Add(j)
대신 list.Insert(0, j)
를 사용했다면
ToArray(): 1, 2, 3, 4
ToArray(): 1, 2, 3, 4, 5, 0, 0, 0, 0
ToArray(): 1, 2, 3, 4, 5, 6, 7, 0, 0
ToArray(): 0, 0, 0, 0, 0, 0, 0, 0, 0
ToArray(): 1, 2, 3, 4, 5, 0, 0, 0, 0
ToArray(): 0, 0, 0, 4, 5, 6, 7
ToArray(): 1, 2, 0, 0, 0, 0, 0, 0, 0
ToArray(): 1, 2, 3
ToArray(): 1, 0, 0, 0, 0, 0, 0, 0, 0
ToArray(): 0, 0, 0, 0, 0, 0, 0, 0
ToArray(): 1, 2
ToArray(): 1, 2, 3
ToArray(): 0, 0, 0, 0, 0, 0, 0, 0
ToArray(): 1, 2, 3, 4
ToArray(): 1, 2, 3, 4, 5, 6, 7, 8
더 유사있을 것입니다.
"때때로"는 무슨 일이 일어나고 있는지를 알려주고 있습니다 : 다른 스레드가 컬렉션을 수정합니다. – Jon
가능한 복제본 [C# 모음이 수정되었습니다. 열거 연산이 실행되지 않을 수 있습니다] (http://stackoverflow.com/questions/2024179/c-sharp-collection-was-modified-enumeration-operation-may-not-execute) – nawfal