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>)
如果索引鍵不存在,則使用指定的函式將索引鍵/值組加入 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)
如果索引鍵不存在,則將索引鍵/值組加入至 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)
若機碼不存在,使用指定的函式與引數將機碼/值組新增到 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);
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 中為 Nothing)。
目錄包含太多項目。
備註
若要修改和寫入字典的作業, ConcurrentDictionary<TKey,TValue> 請使用精細鎖定來確保線程安全。 (字典上的讀取作業是以無鎖定的方式執行。) 不過,委派會在鎖定之外呼叫, valueFactory
以避免在鎖定下執行未知程式代碼時可能發生的問題。 因此, GetOrAdd 對於類別上所有其他作業而言,不是不可部分完成的 ConcurrentDictionary<TKey,TValue> 。
因為索引鍵/值可以在產生值時 valueFactory
由另一個線程插入,所以您無法信任它只是因為 valueFactory
執行,其產生的值會插入字典中並傳回。 如果您在不同的線程上同時呼叫 GetOrAdd , valueFactory
可能會多次呼叫,但字典中只會新增一個索引鍵/值組。
傳回值取決於字典中的索引鍵是否存在,以及呼叫 之後 GetOrAdd 的另一個線程是否插入索引鍵/值,但在產生值之前 valueFactory
:
狀況 | 傳回值 |
---|---|
索引鍵已在字典中。 | 傳回現有的值。 |
索引鍵不在字典中。 valueFactory 會產生值。 重新檢查金鑰時,找不到任何金鑰。 |
索引鍵/值會插入字典中,並傳回值。 |
索引鍵不在字典中。 valueFactory 會產生值。 當 valueFactory 產生值時,不同的線程會插入索引鍵的值。 執行 並重新檢查索引鍵之後 valueFactory ,就會找到另一個線程所插入的索引鍵。 |
傳回另一個線程所插入的值。 |