Queue<T>为什么会隐藏SyncRoot属性?如何实现同步?

5

可能有些困惑,可能错过了一些简单的东西...

我有

var q = new Queue<object>();
lock (q.SyncRoot)
{
    ...
}

我明白了

Queue<T> does not provide a defintion for SyncRoot blah blah...

但是,Queue<T> 实现了 ICollection 接口,该接口定义了 SyncRoot 作为一个公共属性。

首先,为什么这个属性被隐藏了呢?其次,如何隐藏你所实现的接口的属性呢?


你究竟想做什么?我猜你试图使用SyncRoot来避免对队列的并发写入 - 我建议使用ConcurrentQueue - James
@James 我喜欢显式地锁定它。这样在阅读代码时,对我来说更加明显发生了什么。 - Erix
我没有看到你在哪里失去了可读性,但也好。有些人喜欢尝试重新发明轮子的挑战 :) - James
2个回答

6

您可以通过 显式地实现它 来隐藏该属性:

    object MyQueue.SyncRoot { get; set; }

它被隐藏了 因为它已经过时:

我们发现基于SyncRoot的同步API在大多数场景下都不够灵活。这些API允许对集合的单个成员进行线程安全访问。问题在于,有许多情况需要锁定多个操作(例如删除一个项目并添加另一个项目)。换句话说,通常是使用集合的代码想要选择(并实际上可以实现)正确的同步策略,而不是集合本身。我们发现SyncRoot实际上很少使用,在使用它的情况下,它实际上并没有增加太多价值。在不使用它的情况下,它只会给ICollection的实现者带来麻烦。


这看起来真的很不专业。感谢您的见解。 - Erix

3

这是一个关于"显式接口实现"的示例。

当你显式地实现一个接口时,只能通过该类型实例的引用来访问该方法。换句话说,如果你将该Queue强制转换为ICollection,你将看到同步根成员。


+1 为您在手机上回答问题的专注度。我现在也是在手机上评论。 - Ondrej Tucny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接