ConcurrentDictionary<TKey,TValue>.GetOrAdd 方法
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
将键/值对添加到 ConcurrentDictionary<TKey,TValue> 键不存在的情况下。 返回新值;如果键已存在,则返回现有值。
重载
| 名称 | 说明 |
|---|---|
| GetOrAdd(TKey, Func<TKey,TValue>) |
如果键尚不存在,则使用指定的函数将键/值对添加到 ConcurrentDictionary<TKey,TValue> 该对。 返回新值;如果键存在,则返回现有值。 |
| GetOrAdd(TKey, TValue) |
将键/值对添加到 ConcurrentDictionary<TKey,TValue> 键不存在的情况下。 返回新值;如果键存在,则返回现有值。 |
| GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg) |
使用指定的函数和参数(如果该键尚不存在)将键/值对添加到 ConcurrentDictionary<TKey,TValue> 该键或返回现有值(如果该键存在)。 |
示例
以下示例演示如何调用 GetOrAdd 该方法:
class CD_GetOrAddOrUpdate
{
// Demonstrates:
// ConcurrentDictionary<TKey, TValue>.AddOrUpdate()
// ConcurrentDictionary<TKey, TValue>.GetOrAdd()
// ConcurrentDictionary<TKey, TValue>[]
static void Main()
{
// Construct a ConcurrentDictionary
ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>();
// Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates
Parallel.For(0, 10000, i =>
{
// Initial call will set cd[1] = 1.
// Ensuing calls will set cd[1] = cd[1] + 1
cd.AddOrUpdate(1, 1, (key, oldValue) => oldValue + 1);
});
Console.WriteLine("After 10000 AddOrUpdates, cd[1] = {0}, should be 10000", cd[1]);
// Should return 100, as key 2 is not yet in the dictionary
int value = cd.GetOrAdd(2, (key) => 100);
Console.WriteLine("After initial GetOrAdd, cd[2] = {0} (should be 100)", value);
// Should return 100, as key 2 is already set to that value
value = cd.GetOrAdd(2, 10000);
Console.WriteLine("After second GetOrAdd, cd[2] = {0} (should be 100)", value);
}
}
// Demonstrates:
// ConcurrentDictionary<TKey, TValue>.AddOrUpdate()
// ConcurrentDictionary<TKey, TValue>.GetOrAdd()
// ConcurrentDictionary<TKey, TValue>[]
// Construct a ConcurrentDictionary
let cd = ConcurrentDictionary<int, int>()
// Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates
Parallel.For(
0,
10000,
fun i ->
// Initial call will set cd[1] = 1.
// Ensuing calls will set cd[1] = cd[1] + 1
cd.AddOrUpdate(1, 1, (fun key oldValue -> oldValue + 1)) |> ignore
)
|> ignore
printfn $"After 10000 AddOrUpdates, cd[1] = {cd[1]}, should be 10000"
// Should return 100, as key 2 is not yet in the dictionary
let value = cd.GetOrAdd(2, (fun key -> 100))
printfn $"After initial GetOrAdd, cd[2] = {value} (should be 100)"
// Should return 100, as key 2 is already set to that value2
let value2 = cd.GetOrAdd(2, 10000)
printfn $"After second GetOrAdd, cd[2] = {value2} (should be 100)"
' Imports System.Collections.Concurrent
' Imports System.Threading.Tasks
Class CD_GetOrAddOrUpdate
' Demonstrates:
' ConcurrentDictionary<TKey, TValue>.AddOrUpdate()
' ConcurrentDictionary<TKey, TValue>.GetOrAdd()
' ConcurrentDictionary<TKey, TValue>[]
Shared Sub Main()
' Construct a ConcurrentDictionary
Dim cd As New ConcurrentDictionary(Of Integer, Integer)()
' Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates
Parallel.For(0, 10000,
Sub(i)
' Initial call will set cd[1] = 1.
' Ensuing calls will set cd[1] = cd[1] + 1
cd.AddOrUpdate(1, 1, Function(key, oldValue) oldValue + 1)
End Sub)
Console.WriteLine("After 10000 AddOrUpdates, cd[1] = {0}, should be 10000", cd(1))
' Should return 100, as key 2 is not yet in the dictionary
Dim value As Integer = cd.GetOrAdd(2, Function(key) 100)
Console.WriteLine("After initial GetOrAdd, cd[2] = {0} (should be 100)", value)
' Should return 100, as key 2 is already set to that value
value = cd.GetOrAdd(2, 10000)
Console.WriteLine("After second GetOrAdd, cd[2] = {0} (should be 100)", value)
End Sub
End Class
GetOrAdd(TKey, Func<TKey,TValue>)
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
如果键尚不存在,则使用指定的函数将键/值对添加到 ConcurrentDictionary<TKey,TValue> 该对。 返回新值;如果键存在,则返回现有值。
public:
TValue GetOrAdd(TKey key, Func<TKey, TValue> ^ valueFactory);
public TValue GetOrAdd(TKey key, Func<TKey,TValue> valueFactory);
member this.GetOrAdd : 'Key * Func<'Key, 'Value> -> 'Value
Public Function GetOrAdd (key As TKey, valueFactory As Func(Of TKey, TValue)) As TValue
参数
- key
- TKey
要添加的元素的键。
- valueFactory
- Func<TKey,TValue>
用于为键生成值的函数。
返回
键的值。 如果键已在字典中,则为键的现有值;如果键不在字典中,则为新值。
例外
key 或 valueFactory 为 null.
字典包含过多的元素。
注解
对于对字典的修改和写入操作, ConcurrentDictionary<TKey,TValue> 请使用精细锁定来确保线程安全。 (字典上的读取操作以无锁方式执行。但是, valueFactory 委托在锁外调用,以避免在锁下执行未知代码时可能出现的问题。 因此, GetOrAdd 对于类上 ConcurrentDictionary<TKey,TValue> 所有其他操作,不是原子性的。
由于键/值可以由另一个线程在生成值时 valueFactory 插入,因此不能信任仅因为 valueFactory 执行,其生成的值将插入字典并返回。 如果同时在不同线程上调用 GetOrAdd , valueFactory 可以多次调用,但只会将一个键/值对添加到字典中。
返回值取决于字典中是否存在键,以及某个键/值是否由另一个线程在调用后 GetOrAdd 插入,但在生成值之前 valueFactory :
| 情景 | 返回值 |
|---|---|
| 密钥已在字典中。 | 返回现有值。 |
键不在字典中。
valueFactory 生成值。 重新检查密钥时,找不到任何密钥。 |
键/值插入字典中,并返回该值。 |
键不在字典中。
valueFactory 生成值。 生成值时 valueFactory ,其他线程会插入键的值。 执行并重新检查密钥后 valueFactory ,将找到另一个线程插入的键。 |
返回由另一个线程插入的值。 |
另请参阅
适用于
GetOrAdd(TKey, TValue)
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
将键/值对添加到 ConcurrentDictionary<TKey,TValue> 键不存在的情况下。 返回新值;如果键存在,则返回现有值。
public:
TValue GetOrAdd(TKey key, TValue value);
public TValue GetOrAdd(TKey key, TValue value);
member this.GetOrAdd : 'Key * 'Value -> 'Value
Public Function GetOrAdd (key As TKey, value As TValue) As TValue
参数
- key
- TKey
要添加的元素的键。
- value
- TValue
要添加的值(如果键尚不存在)。
返回
键的值。 如果键已在字典中,则为键的现有值;如果键不在字典中,则为新值。
例外
key 是 null。
字典包含过多的元素。
另请参阅
适用于
GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg)
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
使用指定的函数和参数(如果该键尚不存在)将键/值对添加到 ConcurrentDictionary<TKey,TValue> 该键或返回现有值(如果该键存在)。
public:
generic <typename TArg>
TValue GetOrAdd(TKey key, Func<TKey, TArg, TValue> ^ valueFactory, TArg factoryArgument);
public TValue GetOrAdd<TArg>(TKey key, Func<TKey,TArg,TValue> valueFactory, TArg factoryArgument) where TArg : allows ref struct;
public TValue GetOrAdd<TArg>(TKey key, Func<TKey,TArg,TValue> valueFactory, TArg factoryArgument);
member this.GetOrAdd : 'Key * Func<'Key, 'Arg, 'Value> * 'Arg -> 'Value
Public Function GetOrAdd(Of TArg) (key As TKey, valueFactory As Func(Of TKey, TArg, TValue), factoryArgument As TArg) As TValue
类型参数
- TArg
要传入 valueFactory的参数的类型。
参数
- key
- TKey
要添加的元素的键。
- valueFactory
- Func<TKey,TArg,TValue>
用于为键生成值的函数。
- factoryArgument
- TArg
要传入 valueFactory的参数值。
返回
键的值。 如果键已在字典中,则为键的现有值;如果键不在字典中,则为新值。
例外
key 是null引用(Visual Basic中没有任何内容)。
字典包含过多的元素。
注解
对于对字典的修改和写入操作, ConcurrentDictionary<TKey,TValue> 请使用精细锁定来确保线程安全。 (字典上的读取操作以无锁方式执行。但是, valueFactory 委托在锁外调用,以避免在锁下执行未知代码时可能出现的问题。 因此, GetOrAdd 对于类上 ConcurrentDictionary<TKey,TValue> 所有其他操作,不是原子性的。
由于键/值可以由另一个线程在生成值时 valueFactory 插入,因此不能信任仅因为 valueFactory 执行,其生成的值将插入字典并返回。 如果同时在不同线程上调用 GetOrAdd , valueFactory 可以多次调用,但只会将一个键/值对添加到字典中。
返回值取决于字典中是否存在键,以及某个键/值是否由另一个线程在调用后 GetOrAdd 插入,但在生成值之前 valueFactory :
| 情景 | 返回值 |
|---|---|
| 密钥已在字典中。 | 返回现有值。 |
键不在字典中。
valueFactory 生成值。 重新检查密钥时,找不到任何密钥。 |
键/值插入字典中,并返回该值。 |
键不在字典中。
valueFactory 生成值。 生成值时 valueFactory ,其他线程会插入键的值。 执行并重新检查密钥后 valueFactory ,将找到另一个线程插入的键。 |
返回由另一个线程插入的值。 |