현재 Observer 디자인 상황을 구현 중입니다.멀티 스레드 옵저버 패턴에서 사용할 컬렉션은 무엇입니까?
본인의 메인 클래스에 등록 된 옵서버 목록이 있습니다.
private static volatile List<IObserver> registeredObservers;
각 관찰자는 네트워크 소켓, 소켓이 연결되어 있고 모두가 좋은 경우, 그것은 관찰 클래스 자체를 등록합니다. 오류가 있거나 소켓이 단순히 연결을 끊으면 관측 대상에서 자신을 등록 해제/제거합니다.
이 모든 것이 잘 작동하는 것 같습니다. 나는 행복하다.
private void SendEventToObservers(ILogItem item)
{
foreach (var observer in registeredObservers)
{
if (observer != null)
{
observer.OnMessageRecieveEvent(new ObserverEvent(item));
}
}
}
이 후 다음과 같은 오류가 발생합니다 : : 그래서 스레드 이제
Collection was modified; enumeration operation may not execute
나는 다른에 읽은를
하지만 지금 내 주요 클래스 I 루프에서 다음과 같이 등록 된 모든 관찰자를 통해
각각에 대해 .ToList()를 추가하려면 다음과 같이 변경해야합니다.foreach (var observer in registeredObservers.ToList())
이제 q uto는 내 문제를 해결합니다. 왜냐하면 Observer가 루프를 반복하는 동안 목록에서 자체를 제거하면 .toList()가 목록의 "이전"표현을 생성하기 때문입니다.
액세스 할 때와 관찰자가 추가 및 제거 될 때 차단할 수있는 더 나은 동시 정렬 목록이 없을 것이라고 생각 했습니까?
현재의 .ToList() 솔루션이 작동합니까?
FWIW의 사본 반복, 나는 volatile' 당신이 여기에 무엇을 기대하고있다'생각하지 않습니다. 'List'객체에 대한 * reference *는 목록 자체의 내용이 아니라 여기에서 휘발성이 있습니다. 목록 자체를 변경할 계획이 아니라면 권하고 싶지 않습니다. 당신은 아마'readonly'을 만드는 것이 더 좋을 것입니다. ... –
또한 읽을만한 가치가 있습니다 : http://msdn.microsoft.com/en-us/library/dd997305%28v=vs.110%29.aspx –
toList()에 대한 주석은 제 의견으로는 상당히 좋았습니다. 확실히 그것은 목록의 "오래된"표현을 생성하지만 반복하는 동안 목록에서 요소를 삭제하므로이 컬렉션의 다른 인스턴스를 사용해야합니다. 따라서 iterating이 registerObservers의 요소를 변경하는 동안 실제 루프는 변경할 수없는이 목록의 복사본을 사용합니다. – HimBromBeere