并发字典锁定

Concurent dictionary locking

我目前正在阅读我们外部人员交付的代码,但我不理解这部分代码:

    private ConcurrentDictionary<Int64, Person> users = new ConcurrentDictionary<Int64, Person>();
    private Dictionary<String, Int64> connectionIndex = new Dictionary<String, Int64>();

    public Boolean AddNewUser(Int64 userId, Person user) {
        Boolean added = false;
        lock (users) {

            if (users.Select(X=>X.Key==userId).Count()>0)
            {
                Person usrtmp = new Person();
                users.TryRemove(userId,out usrtmp)
            }
                added = users.TryAdd(userId, user);
                if (added)
                {
                    connectionIndex.Add(user.ConnectionId, userId);
                }

        }
        return added;   
    }

为什么 "users concurrent dictionary" 在对该字典的任何操作完成之前被锁定?有必要吗?从我的角度来看,不需要 lock 语句,因为 ConcurrentDictionary 包含线程安全操作。我对吗? 此外,当您在 ConcurrentDictionary 上使用 .Count() 或 Key、Value 操作时,我知道 "performance issue" 。从这个角度来看,LINQ 语句可以吗?

感谢您的回答。

Why "users concurrent dictionary" is locked before any operation on that dictionary is done? Is it necessary?

考虑到他们的使用方式,这把锁当然是必要的。他们在多个不同的字典上执行多个操作,重要的是在发生这种情况时,没有其他线程以任何方式与任何一个字典交互。这样做需要 lock

您可以解除锁定的唯一方法是,如果您到达共享数据结构的唯一用途是对单个并发字典的一个单一 方法调用的地步。在不知道确切要求的情况下,我们无法知道这是否可能,但如果需要两个词典,那肯定不是。

现在,鉴于您已将自己置于始终需要锁定对并发字典的所有访问的位置,因此没有理由使用并发字典而不是常规字典;您已经决定使用自己的同步。

From my point of view is lock statement unnecessary because ConcurrentDictionary contains thread-safe operations. Am I right?

没有。对于新手来说,非并发字典不加锁是无法访问的

Also, I know about "performance issue" when you use .Count() or Key, Value operations on ConcurrentDictionary. Is it LINQ statement OK in this point of view?

出于很多原因,这是一个可怕的想法。它试图通过字典进行线性搜索以查看键是否存在。你不应该永远那样做。您应该使用 ContainsKey。此外,如果在尝试删除密钥之前检查密钥是否存在是没有意义的,您可以尝试将其删除并查看会发生什么。如果您还没有锁定它也是完全不安全的,因为其他人可能会在您迭代字典时更改它,并且它可能会在您搜索后更改,从而在做任何事情之前进行检查毫无意义,因为您不能假设您刚刚检查的内容是真实的。