为什么要锁定Collection.SyncRoot而不是只锁定集合?

时间:2011-06-29 17:57:19

标签: .net icollection syncroot

我试图理解ICollection中同步的意义。为什么不直接锁定集合?

lock(myCollection)
{
    //do stuff to myCollection
}

VS

lock(myCollection.SyncRoot)
{
    //do stuff to myCollection
}

2 个答案:

答案 0 :(得分:8)

通常情况下,如果线程安全是一个严重问题,我会避免使用这些选项。

更好的选择通常是维护自己的私有变量,并在需要的所有方法中锁定它 - 包括访问集合的整个公共API。

真正的危险在于,通过锁定暴露或可能暴露于外部世界的类型,您可能会打开“外部世界”混乱同步的能力。如果使用多个锁,则可能导致死锁(如果外部锁定了您不期望的内容)。

通过创建私有变量并专门锁定它,您可以“控制”这种情况。这使得更清楚的是发生了什么。此外,它可以简化多个对象之间的同步,尤其是在您维护代码之后,因为锁定非常清晰。

答案 1 :(得分:1)

永远不要锁定SyncRoot,因为我相信它会锁定整个集合的锁定(这个)。如果你要锁定,你应该创建一个对象并锁定它。例如

public class MyClass
{
   get {return lock(_lockObject) _myCollection ; }
   set {lock(_lockObject) _myCollection.Add(value); }


   private List<string> _myCollection = new List<string>();
   private object _lockObject = new object();
}

为了更好地澄清, lock(myCollection.SyncRoot)和lock(myCollection)做同样的事情 因为属性SyncRoot看起来像这样

get {return this; }