Development Tip

C# - "System.InvalidOperationException: 컬렉션이 수정되었습니다" 오류

MoonLight314 2024. 2. 24. 13:04
728x90

안녕하세요, MoonLight입니다.

C#에서 Multi Thread or Task 작업 중에 'System.InvalidOperationException: 컬렉션이 수정되었습니다. 열거 작업이 실행되지 않을 수도 있습니다.'라는 Exception을 보신적이 있을 것입니다.

Multi Thread 혹은 Multi Task을 사용하다 보면 여러 Thread or Task에서 공통으로 사용해야 하는 값들이 있을 것입니다.

흔히 이것을 공유 자원이라고 하고 공유 자원을 여러 Thread에서 잘 사용할 수 있도록 조절하는 것을 동기화라고 하죠.

결론적으로, 동기화 문제를 해결하는 방법은 하나의 Thread에서 공유 자원을 사용하고 있으면 다른 Thread들에서는 사용하지 못하게 막는 것입니다.

이 방법을 각 Language들이 지원해 주고 있으며, C#에서도 물론 지원하고 있습니다.

Thread Safe한 Collection인 ConcurrentQueue가 있습니다.

이는 .Net 4.0부터 지원되며, Queue와 Stack의 Thread Safe 버전입니다.

 

1. 선언

System.Collections.Concurrent가 필요하며, 선언은 다음과 같습니다.

ConcurrentQueue<T> 변수

예를 들면, int 값을 저장하는 ConcurrentQueue는 다음과 같이 선언하면 됩니다.

ConcurrentQueue<int> cq = new ConcurrentQueue<int>();

2. 사용법

2.1. 추가

Queue에 Item을 추가하는 방법은 .Enqueue() Method를 사용하면 됩니다.

cq.Enqueue(3);

2.2. 읽어내기

Queue에서 Item을 읽어낼 때는 TryDequeue() Method를 사용하면 됩니다.

int t; 
cq.TryDequeue(out t)

 

2.3. Iteration

Queue 전체 값을 다 읽어내기 위해서는 손쉽게 foreach를 사용하면 됩니다.

 

foreach (int i in cq)

2.4. Clear

ConcurrentQueue는 자체적으로 전체 Queue 값을 Clear하는 Method가 없어서 다음과 같이 하나씩 다 읽어내 줘야 합니다. 조금 불편하네요.

int t; 
while (cq.TryDequeue(out t)) ;

2.5. Item Count

전체 Item 갯수는 .Count Attribute를 참조하면 됩니다.

cq.Count

이번 Post에서는 Thread-Safe한 Queue를 알아보았는데요, 눈치채셨겠지만, Thread-Safe한 Stack도 ConcurrentStack<T>가 있으니 필요하다면 사용하시면 됩니다.

도움이 되셨으면 좋겠네요. 그럼, 다음에 또 만나요~!

728x90