【发布时间】:2014-06-08 13:49:08
【问题描述】:
查看 ConcurrentDictionary 文档,它说以下内容:
表示一个线程安全的键/值对集合,可以 多个线程同时访问。
现在阅读本文时,我觉得我可以调用 ConcurrentDictionary API 中的任何方法,并且它是线程安全的……但这意味着也包括显式实现,我有这个保证吗?
我的例子是如果我想要一个原子操作从 ConcurrentDictionary 中删除一个项目,如果它的值是某个值。
所以我可以这样做:
var concurrentDictionary = new ConcurrentDictionary<string, string>();
concurrentDictionary.TryAdd("hey", "ho");
((ICollection<KeyValuePair<string, string>>) concurrentDictionary).Remove(new KeyValuePair<string, string>("hey", "ho"));
现在我查看了源代码,该操作既是原子安全的又是线程安全的,但它不在 ConcurrentDictionary API 上的事实是否意味着我不应该使用它……或者我正在使用收集做一些我不应该用它做的事情。
我可以更进一步,编写如下扩展方法:
public static boolean TryRemove(this ICollection<KeyValuePair<TKey, TValue>> collection, TKey key, TValue value)
{
return collection.Remove(new KeyValuePair<TKey, TValue>(key, value));
}
这将出现在 ConcurrentDictionary 的 Intellisense 中,因为它实现了 ICollection 接口,许多开发人员甚至可能不知道有什么不好的地方(如果真的有什么不好的地方?!)
编辑: 我所说的“隐式记录”的意思是 ConcurrentDictionary 实现了一组接口。它的文档说它的线程是安全的,但没有说明它是否仅适用于该页面上列出的方法,而是暗示实例上的所有操作都是安全的。
【问题讨论】:
-
@SLaks,对……唔……我的周末阅读能力不是很好。我将删除我的评论以避免进一步混淆......
-
显式 ICollection.Remove() 方法已经调用 TryRemove(),所以你的扩展方法没有用。您只能保证 ConcurrentDictionary 是线程安全的,您所做的事情不会继承该保证。
-
@HansPassant - 仅供参考,它调用私有(内部) TryRemove 方法,该方法以原子方式执行操作:
return TryRemoveInternal(keyValuePair.Key, out throwAwayValue, true, keyValuePair.Value);
标签: c# .net concurrentdictionary