C# 为什么ConcurrentDictionary有AddOrUpdate和GetOrAdd,而Dictionary没有?
在.NET框架中,有C# 为什么ConcurrentDictionary有AddOrUpdate和GetOrAdd,而Dictionary没有?,c#,.net,dictionary,concurrentdictionary,C#,.net,Dictionary,Concurrentdictionary,在.NET框架中,有字典和并发字典。 这些提供了类似于添加、删除等方法 我知道当我们设计多线程程序时,为了线程安全,我们使用concurrentdirectionary替换Dictionary 我想知道为什么concurrentdirectionary有AddOrUpdate,GetOrAdd和类似的方法,而Dictionary没有 我们总是喜欢使用下面的代码从字典中获取对象: var dict = new Dictionary<string, object>(); object t
字典
和并发字典
。
这些提供了类似于添加、删除等方法
我知道当我们设计多线程程序时,为了线程安全,我们使用concurrentdirectionary
替换Dictionary
我想知道为什么concurrentdirectionary
有AddOrUpdate
,GetOrAdd
和类似的方法,而Dictionary
没有
我们总是喜欢使用下面的代码从字典
中获取对象:
var dict = new Dictionary<string, object>();
object tmp;
if (dict.ContainsKey("key"))
{
tmp = dict["key"];
}
else
{
dict["key"] = new object();
tmp = new object();
}
我希望.NET有这些方法,但为什么没有呢?因为这些方法是:
Get
和Add
分为两个单独的步骤,并且仍然会产生正确的结果Dictionary
实现时,它隐式地表示某种级别的线程安全性,好像Dictionary
可以正确地处理这个问题。它不能,所以它只是没有实现。这并不能阻止您使用扩展方法来做类似的事情
public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, Func<string, TValue> valueGenerator)
{
//
// WARNING: this method is not thread-safe and not intended as such.
//
if (!dict.TryGetValue(key, out TValue value))
{
value = valueGenerator(key);
dict.Add(key, value);
}
return value;
}
public static TValue GetOrAdd(此字典dict dict,TKey key,Func valueGenerator)
{
//
//警告:此方法不是线程安全的,也不是线程安全的。
//
如果(!dict.TryGetValue(键,输出值))
{
值=值生成器(键);
dict.Add(键、值);
}
返回值;
}
ConcurrentDictionary有这些方法,因为它们可以防止竞争条件,Dictionary不需要这些方法,因为它本质上是线程不安全的。谢谢。好的,那么.Net来确保为开发人员提供这些方法是安全的。实际上,对于字典来说,将方法放在其中是有意义的,不是从线程安全的角度,而是从优化的角度。字典已经计算出它期望该项位于哪个存储桶中,而不是哪个存储桶中,然后它可以直接将该项放入该存储桶中。使用tryget+add时,它必须对密钥进行两次散列。从这个角度来看,确实如此,但在这方面,它“仅仅”是一种编码的性能优化。我觉得.NET可以在这方面做一些认真的工作@LasseVågsætherKarlsenAlso,当
字典
被引入时,没有lambdas这样的东西。如果总是要传递创建的实例,而不是Func
@LasseV.Karlsen,那么效率可能会降低。因此,如果确实需要,构建“更快”的字典类很容易。我总是想知道为什么那些显而易见的成员被排除在外。
public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, Func<string, TValue> valueGenerator)
{
//
// WARNING: this method is not thread-safe and not intended as such.
//
if (!dict.TryGetValue(key, out TValue value))
{
value = valueGenerator(key);
dict.Add(key, value);
}
return value;
}