【问题标题】:EventAggregator, is it thread-safe?EventAggregator,它是线程安全的吗?
【发布时间】:2010-05-14 12:24:14
【问题描述】:

这是线程安全的吗?

Prism 中的 EventAggregator 是一个非常简单的类,只有一个方法。当我注意到 null 检查和创建新类型以添加​​到私有 _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;
    }

【问题讨论】:

    标签: wpf silverlight prism eventaggregator


    【解决方案1】:

    不,不是线程安全的。

    1. 根据MSDN under Thread safety,List 类本身的实例成员访问不是线程安全的
    2. 方法本身不是线程安全的
      1. 2个线程可以同时进入方法
      2. 两者都尝试获取 FirstOrDefault
      3. 两者都一无所获
      4. 两者都添加了新的 TEventType

    我愿意

    1. 切换到 .NET 4 中的 System.CollectionConcurrentX 集合之一
      http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx
    2. 自己加锁

    【讨论】:

    • +1 @Peter 同意。在遇到一些问题后,我来到这里进行完整性检查,然后在反射器中查看 EventAggregator 的代码。鉴于预期的架构用途,我无法相信他们没有使其成为线程安全的。反正我很惊讶。
    • @chibacity 我也很惊讶 ;-)
    【解决方案2】:

    这取决于“_events”是什么......

    .NET 4 中有一些很棒的新线程安全类 ...
    查看http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx

    【讨论】:

    • 对不起,我应该把它包括在内。它只是一个列表:私有只读 List _events = new List();
    【解决方案3】:

    好吧,根据那个代码粘贴,我会说不,它不是 100% 线程安全的。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 2011-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多