2010-05-14 5 views
6

이 스레드로부터 안전한가요?EventAggregator, 스레드로부터 안전합니까?

프리즘의 EventAggregator는 단 하나의 메소드가있는 매우 간단한 클래스입니다. Null 검사와 개인 _events 컬렉션에 추가 할 새 유형 생성과 관련된 문제가 없다는 사실에 놀랐습니다. 동일한 유형 (_events에 존재하기 전에) 동안 두 개의 스레드가 GetEvent를 동시에 호출하면 콜렉션에 두 개의 항목이 생기는 것처럼 보입니다.

/// <summary> 
    /// Gets the single instance of the event managed by this EventAggregator. Multiple calls to this method with the same <typeparamref name="TEventType"/> returns the same event instance. 
    /// </summary> 
    /// <typeparam name="TEventType">The type of event to get. This must inherit from <see cref="EventBase"/>.</typeparam> 
    /// <returns>A singleton instance of an event object of type <typeparamref name="TEventType"/>.</returns> 
    public TEventType GetEvent<TEventType>() where TEventType : EventBase 
    { 
     TEventType eventInstance = _events.FirstOrDefault(evt => evt.GetType() == typeof(TEventType)) as TEventType; 
     if (eventInstance == null) 
     { 
      eventInstance = Activator.CreateInstance<TEventType>(); 
      _events.Add(eventInstance); 
     } 
     return eventInstance; 
    } 

답변

4

아니요, 스레드로부터 안전하지 않습니다.

  1. 방법 자체이 스레드되지 MSDN under Thread safety
  2. 에 따라 자체 안전 스레드하지 이다 List 클래스의 인스턴스 멤버 액세스,
  3. 2 개 스레드가 방법을 입력 할 수
      안전 동시에
    1. 두 가지 모두 FirstOrDefault를 가져 오려고 시도하십시오.
    2. 두 아무것도에게
    3. 를 얻을 모두 새로운 TEventType

를 추가 나는 것

  1. 스위치 .NET에서 System.CollectionConcurrentX의 컬렉션 중 하나에 4
    http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx
    또는
  2. 나만의 잠금 수행
+0

+1 @Peter Agreed. 나는 약간의 문제가 생긴 후에 온건주의 체크를하기 위해 여기에 왔고 반사경에있는 EventAggregator 코드를 살펴 보았다. 의도 한 아키텍처를 사용하여 thread-safe로 만들지 못했다고 나는 믿을 수 없다. 어쨌든 나는 놀랐다. –

+0

@chibacity 나도 놀랐어 ;-) –

0

우물이있다, 기반 ... "_events는"무엇 달려있다 그 코드 붙여 넣기, 아니, 100 % 스레드 안전하지 않습니다.

물론 소스가 있으므로 자물쇠를 직접 추가 할 수 있습니다. :)

사실, 일반적으로 경험적으로, 적어도 처음에는 전체 솔루션을 CAL 프로젝트에 포함 시켰습니다. 그것은 이상한 지역 등록/생성 예외를 디버깅하는 데 많은 도움이됩니다. ...