ConcurrentDictionary TryRemove何时返回false


79

它会仅在字典中不包含给定键的值的情况下才返回false还是由于线程争用条件而返回false,例如另一个线程添加/更新某些内容?

代码中的问题:

ConcurrentDictionary<int, string> cd = new ConcurrentDictionary<int, string>();

// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one"); 

// Will this ever fail if no other thread ever removes with the key value of 1?
cd.TryRemove(1); 

编辑: 我认为,如果它不包含给定键的值,则它只会返回false,但要绝对确定。

Answers:


84

虽然米奇(Mitch)认为aConcurrentDictionary不受比赛条件的影响是正确的,但我认为您所提出的问题的答案是,是的,如果钥匙存在,TryRemove它将起作用并返回true

在您发布的代码中,没有办法TryRemove返回,false因为cd是在其他任何地方都无法访问的局部变量。但是,如果其他地方的某些代码被赋予了对该ConcurrentDictionary对象的引用,并且正在删除单独线程上的键,那么即使在这里,也有TryRemove可能返回该false结果,但这仅是因为该键已被删除,而不是因为正在执行其他操作。字典和键就以某种方式“卡在”那里。


5

ConcurrentDictionary不从比赛条件受到影响。这就是为什么要使用它。

返回值

如果成功删除对象,则为true;否则为false。否则为假。


2

还有一点要说明:

// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one"); 

该评论是不正确的,并且可能对“尝试”的含义有相同的误解。这与并发添加无关,而是是否已经使用key添加了值1

考虑一个标准Dictionary<TKey,TValue>。等效代码为:

if (!d.Contains(1))
    d.Add(1, "one");

这需要两个操作。有没有办法来设计这样的API是线程安全的,因为cd可能有一个键的值1调用之间添加ContainsAdd,那么这将导致Add投掷。

并发集合具有API,这些API在逻辑上将这些“测试与执行”对捆绑到单个API后面的单个原子操作中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.