7

我试图了解 ICollection 中同步根的意义。为什么不直接锁定收藏?

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

对比

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

2 回答 2

8

通常,如果线程安全是一个严重的问题,我会避免使用这些选项中的任何一个。

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

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

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

于 2011-06-29T18:05:47.410 回答
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 看起来像这样

得到{返回这个;}

于 2011-06-29T18:04:17.190 回答