在if语句中使用ConcurrentDictionary TryGetValue是否使if内容成为线程安全的?

时间:2012-11-07 20:45:29

标签: c# concurrency

如果我有一个ConcurrentDictionary并在if语句中使用TryGetValue,这是否会使if语句的内容线程安全?或者你必须在if语句中锁定吗?

示例:

        ConcurrentDictionary<Guid, Client> m_Clients;

        Client client;
        //Does this if make the contents within it thread-safe? 
        if (m_Clients.TryGetValue(clientGUID, out client))
        {
            //Users is a list.
            client.Users.Add(item);
        }

或者我必须这样做:

        ConcurrentDictionary<Guid, Client> m_Clients;

        Client client;
        //Does this if make the contents within it thread-safe? 
        if (m_Clients.TryGetValue(clientGUID, out client))
        {
            lock (client)
            {
                //Users is a list.
                client.Users.Add(item);
            }
        }

2 个答案:

答案 0 :(得分:5)

是的,您必须在if语句中锁定,您从并发字典获得的唯一保证是它的方法是线程保存。

答案 1 :(得分:2)

根据您的观点和您尝试实现的线程安全范围,接受的答案可能会产生误导。这个答案针对的是那些在学习线程和并发的同时偶然发现这个问题的人:

确实,锁定字典检索的输出(Client对象)使代码线程的部分安全,但是只能访问锁中的检索对象的代码。在该示例中,在当前线程检索它之后,另一个线程可能从字典中删除该对象。 (即使检索和锁之间没有语句,其他线程仍然可以在其间执行。)然后,此代码将Client对象添加到Users列表,即使它不再在并发字典中。这可能会导致异常,同步或竞争条件。

这取决于程序的其余部分在做什么。但是在我所描述的场景中,将锁定放在整个字典检索中会更安全。然后常规字典可能比并发字典更快更简单,只要你在使用它时总是锁定它!