Concurent字典锁定

时间:2018-01-10 16:44:08

标签: c# concurrency concurrentdictionary

我目前正在阅读我们的外部人员提供的代码,我不明白这部分代码:

    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;   
    }

为什么“用户并发字典”在对该字典的任何操作完成之前被锁定?有必要吗?从我的观点来看,锁定语句是不必要的,因为ConcurrentDictionary包含线程安全的操作。我对吗? 此外,当您在ConcurrentDictionary上使用.Count()或Key,Value操作时,我知道“性能问题”。从这个角度来看LINQ语句是否正常?

感谢您的回答。

1 个答案:

答案 0 :(得分:2)

  

为什么&#34;用户并发字典&#34;在该字典的任何操作完成之前被锁定?有必要吗?

锁定肯定是必要的,因为他们如何使用它。他们在多个不同的词典上执行多个操作,并且在发生这种情况时,任何其他线程都不会以任何方式与任何字典进行交互,这一点非常重要。这样做需要lock

您可以删除锁定的唯一方法是,如果您在单个并发字典上使用共享数据结构的唯一用法是单个方法调用。在不知道具体要求的情况下,我们无法知道这是否可行,但如果需要两个字典,那么它肯定不是。

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

  

从我的观点来看,lock语句是不必要的,因为ConcurrentDictionary包含线程安全的操作。我对吗?

没有。对于初学者来说,没有锁定就无法访问非并发字典

  

另外,我知道&#34;性能问题&#34;当您在ConcurrentDictionary上使用.Count()或Key,Value操作时。从这个角度来看LINQ语句是否正常?

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