2011-03-31 5 views
1

수정되지 않습니다 "때때로, 나는 아래의 메시지가컬렉션이 수정되었습니다. .. 열거 작업이 실행되지 않을 수 있습니다 내 코드의 구조 ","컬렉션의 요소가 나는 중첩 루프를

컬렉션이 수정되었다. 열거 작업이 실행되지 않을 수 있습니다.

나는 다음과 같은 통해 반복하고 컬렉션이 있습니다. Coll이 배열의 각 문자열를 들어 List<string>

foreach (string[] s1 in obj.Coll 
{ 
    foreach (string s in s1) { } 
} 

, 나는 t 필요 o 그것으로 작업한다. (값을 읽지 않고 쓰지 않는다). 내가 할 일은 디렉터리를 얻는 것뿐입니다 (이 값은 경로 임).이 문자열을 배열로 나눕니다.

어떻게 해결할 수 있습니까?

+1

"때때로"는 무슨 일이 일어나고 있는지를 알려주고 있습니다 : 다른 스레드가 컬렉션을 수정합니다. – Jon

+0

가능한 복제본 [C# 모음이 수정되었습니다. 열거 연산이 실행되지 않을 수 있습니다] (http://stackoverflow.com/questions/2024179/c-sharp-collection-was-modified-enumeration-operation-may-not-execute) – nawfal

답변

0

당신이 시도 할 수 : 반복을 시작하기 전에 사본을 취할 것

foreach (string[] s1 in obj.Coll.ToArray()) 
{ 

!

+1

컬렉션이있는 경우에만 작동합니다 유의하십시오. ToArray()가 쓰레드에 안전하지 않기 때문에 다른 쓰레드에 의해 변경되지 않는다. – mgronber

+0

나는 여러 번의 오류나 문제가없는 무거운로드 다중 스레드 응용 프로그램에서이 프로그램을 사용 했습니까? –

+0

문제를 설명하기 위해 내 대답을 편집했습니다. – mgronber

2

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 

더 유사있을 것입니다.

관련 문제