Hashtable转换为Dictionary<>的同步根。

12

哈希表有一个syncroot属性,但通用字典没有。如果我的代码是这样的:

lock (hashtable.Syncroot)
{
....
}

如果我删除哈希表并改用通用字典,该如何复制这个功能?

4个回答

12
如果你想要严格的兼容性,那么Bryan是正确的。 这是在字典中保持当前语义的最佳方法。
但是,更进一步来说,SyncRoot属性没有被直接添加到通用字典中是因为这是一种危险的同步方式。它只比“lock(this)”略好,而后者非常危险且容易出现死锁。以下是一些解释为何这样做很糟糕的链接。

6
完全同意。然而,当人们回答“这样做不好”时,我真的很讨厌:)。大多数时候,人们问问题时通常被困在特定场景中,需要解决问题。我试图在解决问题的同时,给出关于为什么这样做不好以及如何避免的建议。 - JaredPar

7
新的SyncRoot思想认为原始设计存在错误。如果唯一需要锁定的是字典且其为私有对象,则可以锁定它或另一个作为同步对象的对象。当您要保护的状态不仅仅是字典时,后一种技术非常有用。
// used as you would have used SyncRoot before
object _syncLock = new object();
Dictionary<string, int> numberMapper = new Dictionary<string, int>();

// in some method...
lock (_syncLock)
{
    // use the dictionary here.
}

你有关于原始设计中存在错误的引用来源吗? - dalle
1
Brad Abrams和Krzysztof Cwalina(.NET的程序经理)这样说:http://blogs.msdn.com/brada/archive/2003/09/28/50391.aspx - netadictos
1
Jeffrey Richter 在《CLR Via C#》一书中也涵盖了这个设计错误。 - user1228

5
var dictionary = new Dictionary<int, string>();

lock(((ICollection) dictionary).SyncRoot)
{
    // ...
}

3
如果哈希表/字典不是公开的,你可以锁定字典对象本身。

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