2010-05-14 94 views
6

这是线程安全的吗?EventAggregator,它是线程安全的吗?

Prism中的EventAggregator是一个非常简单的类,只有一个方法。当我注意到在空检查和创建一个添加到私有_events集合的新类型时没有锁定时,我感到很惊讶。如果两个线程同时调用同一类型的GetEvent(在它存在于_events之前),看起来这将导致集合中有两个条目。

/// <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. List类的实例成员访问本身是不是线程安全,按照MSDN under Thread safety
  2. 方法本身不是线程安全
    1. 2个线程可以输入法同时
    2. 都试图获得FirstOrDefault
    3. 无论得到什么
    4. 两种添加新TEventType

我会

  1. 切换到.NET中的System.CollectionConcurrentX的收藏品之一4
    http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx
  2. 做你自己的锁定
+0

+1 @Peter同意。在遇到一些问题后,我来到这里进行完整性检查,然后在反射器中查看EventAggregator的代码。考虑到预期的建筑使用情况,我无法相信它们不会使其线程安全。反正我很惊讶。 – 2010-09-15 13:00:00

+0

@chibacity我也很惊讶我是;-) – 2010-09-20 04:00:41

0

好了,基于该代码粘贴,我会说不,它不是100%线程安全的。

当然,你有来源,所以你可以自己添加锁。 :)

实际上,作为一般的经验法则,我将整个CAL项目包括在我的解决方案中,至少在开始的时候。它在调试那些奇怪的区域注册/创建例外时有很大帮助...

相关问题