共用方式為


ConcurrentDictionary<TKey,TValue>.GetOrAdd 方法

定義

如果索引鍵不存在,則將索引鍵/值組加入至 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.cs
來源:
ConcurrentDictionary.cs
來源:
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>

用來為索引鍵產生值的函式。

傳回

TValue

索引鍵的值。 這個值將是索引鍵的現有值 (如果字典中已有索引鍵),或是新值 (如果字典中沒有索引鍵)。

例外狀況

keyvalueFactorynull

目錄包含太多項目。

備註

若要修改和寫入字典的作業, ConcurrentDictionary<TKey,TValue> 請使用精細鎖定來確保線程安全。 (字典上的讀取作業是以無鎖定的方式執行。) 不過,委派會在鎖定之外呼叫, valueFactory 以避免在鎖定下執行未知程式代碼時可能發生的問題。 因此, GetOrAdd 對於類別上所有其他作業而言,不是不可部分完成的 ConcurrentDictionary<TKey,TValue>

因為索引鍵/值可以在產生值時 valueFactory 由另一個線程插入,所以您無法信任它只是因為 valueFactory 執行,其產生的值會插入字典中並傳回。 如果您在不同的線程上同時呼叫 GetOrAddvalueFactory 可能會多次呼叫,但字典中只會新增一個索引鍵/值組。

傳回值取決於字典中的索引鍵是否存在,以及呼叫 之後 GetOrAdd 的另一個線程是否插入索引鍵/值,但在產生值之前 valueFactory

狀況 傳回值
索引鍵已在字典中。 傳回現有的值。
索引鍵不在字典中。 valueFactory 會產生值。 重新檢查金鑰時,找不到任何金鑰。 索引鍵/值會插入字典中,並傳回值。
索引鍵不在字典中。 valueFactory 會產生值。 當 valueFactory 產生值時,不同的線程會插入索引鍵的值。 執行 並重新檢查索引鍵之後 valueFactory ,就會找到另一個線程所插入的索引鍵。 傳回另一個線程所插入的值。

另請參閱

適用於

GetOrAdd(TKey, TValue)

來源:
ConcurrentDictionary.cs
來源:
ConcurrentDictionary.cs
來源:
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

索引鍵不存在時要加入的值。

傳回

TValue

索引鍵的值。 這個值將是索引鍵的現有值 (如果字典中已有索引鍵),或是新值 (如果字典中沒有索引鍵)。

例外狀況

keynull

目錄包含太多項目。

另請參閱

適用於

GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg)

來源:
ConcurrentDictionary.cs
來源:
ConcurrentDictionary.cs
來源:
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);
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 的引數值。

傳回

TValue

索引鍵的值。 這個值將是索引鍵的現有值 (如果字典中已有索引鍵),或是新值 (如果字典中沒有索引鍵)。

例外狀況

keynull 參考 (在 Visual Basic 中為 Nothing)。

目錄包含太多項目。

備註

若要修改和寫入字典的作業, ConcurrentDictionary<TKey,TValue> 請使用精細鎖定來確保線程安全。 (字典上的讀取作業是以無鎖定的方式執行。) 不過,委派會在鎖定之外呼叫, valueFactory 以避免在鎖定下執行未知程式代碼時可能發生的問題。 因此, GetOrAdd 對於類別上所有其他作業而言,不是不可部分完成的 ConcurrentDictionary<TKey,TValue>

因為索引鍵/值可以在產生值時 valueFactory 由另一個線程插入,所以您無法信任它只是因為 valueFactory 執行,其產生的值會插入字典中並傳回。 如果您在不同的線程上同時呼叫 GetOrAddvalueFactory 可能會多次呼叫,但字典中只會新增一個索引鍵/值組。

傳回值取決於字典中的索引鍵是否存在,以及呼叫 之後 GetOrAdd 的另一個線程是否插入索引鍵/值,但在產生值之前 valueFactory

狀況 傳回值
索引鍵已在字典中。 傳回現有的值。
索引鍵不在字典中。 valueFactory 會產生值。 重新檢查金鑰時,找不到任何金鑰。 索引鍵/值會插入字典中,並傳回值。
索引鍵不在字典中。 valueFactory 會產生值。 當 valueFactory 產生值時,不同的線程會插入索引鍵的值。 執行 並重新檢查索引鍵之後 valueFactory ,就會找到另一個線程所插入的索引鍵。 傳回另一個線程所插入的值。

適用於