ConcurrentDictionary<TKey,TValue>.AddOrUpdate メソッド

定義

キーがまだ存在しない場合はキーと値のペアを ConcurrentDictionary<TKey,TValue> に追加するか、キーが既に存在する場合は ConcurrentDictionary<TKey,TValue> のキーと値のペアを更新します。

オーバーロード

名前 説明
AddOrUpdate(TKey, Func<TKey,TValue>, Func<TKey,TValue,TValue>)

指定した関数を使用して、キーがまだ存在しない場合は ConcurrentDictionary<TKey,TValue> にキーと値のペアを追加し、キーが既に存在する場合は ConcurrentDictionary<TKey,TValue> のキーと値のペアを更新します。

AddOrUpdate(TKey, TValue, Func<TKey,TValue,TValue>)

キーがまだ存在しない場合は、キーと値のペアを ConcurrentDictionary<TKey,TValue> に追加するか、キーが既に存在する場合は、指定した関数を使用して ConcurrentDictionary<TKey,TValue> 内のキーと値のペアを更新します。

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

指定した関数と引数を使用して、キーがまだ存在しない場合はキーと値のペアを ConcurrentDictionary<TKey,TValue> に追加し、キーが既に存在する場合は ConcurrentDictionary<TKey,TValue> のキーと値のペアを更新します。

次の例は、 AddOrUpdate メソッドを呼び出す方法を示しています。

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

AddOrUpdate(TKey, Func<TKey,TValue>, Func<TKey,TValue,TValue>)

指定した関数を使用して、キーがまだ存在しない場合は ConcurrentDictionary<TKey,TValue> にキーと値のペアを追加し、キーが既に存在する場合は ConcurrentDictionary<TKey,TValue> のキーと値のペアを更新します。

public:
 TValue AddOrUpdate(TKey key, Func<TKey, TValue> ^ addValueFactory, Func<TKey, TValue, TValue> ^ updateValueFactory);
public TValue AddOrUpdate(TKey key, Func<TKey,TValue> addValueFactory, Func<TKey,TValue,TValue> updateValueFactory);
member this.AddOrUpdate : 'Key * Func<'Key, 'Value> * Func<'Key, 'Value, 'Value> -> 'Value
Public Function AddOrUpdate (key As TKey, addValueFactory As Func(Of TKey, TValue), updateValueFactory As Func(Of TKey, TValue, TValue)) As TValue

パラメーター

key
TKey

追加するキー、または値を更新する必要があるキー。

addValueFactory
Func<TKey,TValue>

存在しないキーの値を生成するために使用される関数。

updateValueFactory
Func<TKey,TValue,TValue>

キーの既存の値に基づいて既存のキーの新しい値を生成するために使用される関数。

返品

TValue

キーの新しい値。 これは、 addValueFactory の結果 (キーが存在しない場合) または updateValueFactory の結果 (キーが存在する場合) のいずれかになります。

例外

keyaddValueFactory、または updateValueFactorynull

ディクショナリに含まれる要素が多すぎます。

注釈

異なるスレッドで AddOrUpdate を同時に呼び出す場合、 addValueFactory は複数回呼び出すことができますが、そのキーと値のペアが呼び出しごとにディクショナリに追加されない可能性があります。

ディクショナリに対する変更操作と書き込み操作の場合、 ConcurrentDictionary<TKey,TValue> はきめ細かいロックを使用してスレッドの安全性を確保します (ディクショナリに対する読み取り操作はロック不要の方法で実行されます)。 addValueFactoryおよびupdateValueFactoryデリゲートは、値が期待どおりに追加または更新されたことを確認するために複数回実行できます。 ただし、ロックの下で不明なコードを実行することによって発生する可能性のある問題を回避するために、ロックの外部で呼び出されます。 したがって、 AddOrUpdate は、 ConcurrentDictionary<TKey,TValue> クラスに対する他のすべての操作に関してアトミックではありません。

こちらもご覧ください

適用対象

AddOrUpdate(TKey, TValue, Func<TKey,TValue,TValue>)

キーがまだ存在しない場合は、キーと値のペアを ConcurrentDictionary<TKey,TValue> に追加するか、キーが既に存在する場合は、指定した関数を使用して ConcurrentDictionary<TKey,TValue> 内のキーと値のペアを更新します。

public:
 TValue AddOrUpdate(TKey key, TValue addValue, Func<TKey, TValue, TValue> ^ updateValueFactory);
public TValue AddOrUpdate(TKey key, TValue addValue, Func<TKey,TValue,TValue> updateValueFactory);
member this.AddOrUpdate : 'Key * 'Value * Func<'Key, 'Value, 'Value> -> 'Value
Public Function AddOrUpdate (key As TKey, addValue As TValue, updateValueFactory As Func(Of TKey, TValue, TValue)) As TValue

パラメーター

key
TKey

追加するキー、または値を更新する必要があるキー。

addValue
TValue

存在しないキーに対して追加する値。

updateValueFactory
Func<TKey,TValue,TValue>

キーの既存の値に基づいて既存のキーの新しい値を生成するために使用される関数。

返品

TValue

キーの新しい値。 これは、 addValue (キーが存在しない場合) または updateValueFactory の結果 (キーが存在する場合) のいずれかになります。

例外

key または updateValueFactorynull

ディクショナリに含まれる要素が多すぎます。

次のコード例は、 ConcurrentDictionary<TKey,TValue> を初期化する方法と、AddOrUpdate メソッドを使用してコレクションに項目を追加し、既存の項目を更新する方法を示しています。

using System;
using System.Collections.Concurrent;

class CD_Ctor
{
    // Demonstrates:
    //      ConcurrentDictionary<TKey, TValue> ctor(concurrencyLevel, initialCapacity)
    //      ConcurrentDictionary<TKey, TValue>[TKey]
    static void Main()
    {
        // We know how many items we want to insert into the ConcurrentDictionary.
        // So set the initial capacity to some prime number above that, to ensure that
        // the ConcurrentDictionary does not need to be resized while initializing it.
        int HIGHNUMBER = 64;
        int initialCapacity = 101;

        // The higher the concurrencyLevel, the higher the theoretical number of operations
        // that could be performed concurrently on the ConcurrentDictionary.  However, global
        // operations like resizing the dictionary take longer as the concurrencyLevel rises.
        // For the purposes of this example, we'll compromise at numCores * 2.
        int numProcs = Environment.ProcessorCount;
        int concurrencyLevel = numProcs * 2;

        // Construct the dictionary with the desired concurrencyLevel and initialCapacity
        ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>(concurrencyLevel, initialCapacity);

        // Initialize the dictionary
        for (int i = 1; i <= HIGHNUMBER; i++) cd[i] = i * i;

        Console.WriteLine("The square of 23 is {0} (should be {1})", cd[23], 23 * 23);

        // Now iterate through, adding one to the end of the list. Existing items should be updated to be divided by their
        // key  and a new item will be added that is the square of its key.
        for (int i = 1; i <= HIGHNUMBER + 1; i++)
          cd.AddOrUpdate(i, i * i, (k,v) => v / i);

        Console.WriteLine("The square root of 529 is {0} (should be {1})", cd[23], 529 / 23);
        Console.WriteLine("The square of 65 is {0} (should be {1})", cd[HIGHNUMBER + 1], ((HIGHNUMBER + 1) * (HIGHNUMBER + 1)));
    }
}
open System
open System.Collections.Concurrent

// Demonstrates:
//      ConcurrentDictionary<TKey, TValue> ctor(concurrencyLevel, initialCapacity)
//      ConcurrentDictionary<TKey, TValue>[TKey]

// We know how many items we want to insert into the ConcurrentDictionary.
// So set the initial capacity to some prime number above that, to ensure that
// the ConcurrentDictionary does not need to be resized while initializing it.
let HIGHNUMBER = 64
let initialCapacity = 101

// The higher the concurrencyLevel, the higher the theoretical number of operations
// that could be performed concurrently on the ConcurrentDictionary.  However, global
// operations like resizing the dictionary take longer as the concurrencyLevel rises.
// For the purposes of this example, we'll compromise at numCores * 2.
let numProcs = Environment.ProcessorCount
let concurrencyLevel = numProcs * 2

// Construct the dictionary with the desired concurrencyLevel and initialCapacity
let cd = ConcurrentDictionary<int, int>(concurrencyLevel, initialCapacity)

// Initialize the dictionary
for i = 1 to HIGHNUMBER do
    cd[i] <- i * i

printfn $"The square of 23 is {cd[23]} (should be {23 * 23})"

// Now iterate through, adding one to the end of the list. Existing items should be updated to be divided by their
// key  and a new item will be added that is the square of its key.
for i = 1 to HIGHNUMBER + 1 do
    cd.AddOrUpdate(i, i * i, (fun k v -> v / i)) |> ignore

printfn $"The square root of 529 is {cd[23]} (should be {529 / 23})"
printfn $"The square of 65 is {cd[HIGHNUMBER + 1]} (should be {(HIGHNUMBER + 1) * (HIGHNUMBER + 1)})"
Imports System.Collections.Concurrent

Class CD_Ctor
    ' Demonstrates: 
    '      ConcurrentDictionary<TKey, TValue> ctor(concurrencyLevel, initialCapacity) 
    '      ConcurrentDictionary<TKey, TValue>[TKey] 
    Public Shared Sub Main()
        ' We know how many items we want to insert into the ConcurrentDictionary. 
        ' So set the initial capacity to some prime number above that, to ensure that 
        ' the ConcurrentDictionary does not need to be resized while initializing it. 
        Dim HIGHNUMBER As Integer = 64
        Dim initialCapacity As Integer = 101

        ' The higher the concurrencyLevel, the higher the theoretical number of operations 
        ' that could be performed concurrently on the ConcurrentDictionary.  However, global 
        ' operations like resizing the dictionary take longer as the concurrencyLevel rises.  
        ' For the purposes of this example, we'll compromise at numCores * 2. 
        Dim numProcs As Integer = Environment.ProcessorCount
        Dim concurrencyLevel As Integer = numProcs * 2

        ' Construct the dictionary with the desired concurrencyLevel and initialCapacity
        Dim cd As New ConcurrentDictionary(Of Integer, Integer)(concurrencyLevel, initialCapacity)

        ' Initialize the dictionary 
        For i As Integer = 1 To HIGHNUMBER
            cd(i) = i * i
        Next

        Console.WriteLine("The square of 23 is {0} (should be {1})", cd(23), 23 * 23)

        ' Now iterate through, adding one to the end of the list. Existing items should be updated to be divided by their 
        ' key  and a new item will be added that is the square of its key.
        For i As Integer = 1 To HIGHNUMBER + 1

            cd.AddOrUpdate(i, i * i, Function(k, v)
                                         Return v / i
                                     End Function)
        Next

        Console.WriteLine("The square root of 529 is {0} (should be {1})", cd(23), 529 / 23)
        Console.WriteLine("The square of 65 is {0} (should be {1})", cd(HIGHNUMBER + 1), ((HIGHNUMBER + 1) * (HIGHNUMBER + 1)))

    End Sub
End Class

ディクショナリに対する変更および書き込み操作の場合、 ConcurrentDictionary<TKey,TValue> は細かいロックを使用してスレッド の安全性を確保します。 (ディクショナリに対する読み取り操作は、ロックフリーの方法で実行されます)。 addValueFactory および updateValueFactory デリゲートは、値が期待どおりに追加または更新されたことを確認するために複数回実行できます。 ただし、ロックの下で不明なコードを実行することによって発生する可能性のある問題を回避するために、ロックの外部で呼び出されます。 したがって、 AddOrUpdate は、 ConcurrentDictionary<TKey,TValue> クラスに対する他のすべての操作に関してアトミックではありません。

こちらもご覧ください

適用対象

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

指定した関数と引数を使用して、キーがまだ存在しない場合はキーと値のペアを ConcurrentDictionary<TKey,TValue> に追加し、キーが既に存在する場合は ConcurrentDictionary<TKey,TValue> のキーと値のペアを更新します。

public:
generic <typename TArg>
 TValue AddOrUpdate(TKey key, Func<TKey, TArg, TValue> ^ addValueFactory, Func<TKey, TValue, TArg, TValue> ^ updateValueFactory, TArg factoryArgument);
public TValue AddOrUpdate<TArg>(TKey key, Func<TKey,TArg,TValue> addValueFactory, Func<TKey,TValue,TArg,TValue> updateValueFactory, TArg factoryArgument);
member this.AddOrUpdate : 'Key * Func<'Key, 'Arg, 'Value> * Func<'Key, 'Value, 'Arg, 'Value> * 'Arg -> 'Value
Public Function AddOrUpdate(Of TArg) (key As TKey, addValueFactory As Func(Of TKey, TArg, TValue), updateValueFactory As Func(Of TKey, TValue, TArg, TValue), factoryArgument As TArg) As TValue

型パラメーター

TArg

addValueFactoryおよびupdateValueFactoryに渡す引数の型。

パラメーター

key
TKey

追加するキー、または値を更新する必要があるキー。

addValueFactory
Func<TKey,TArg,TValue>

存在しないキーの値を生成するために使用される関数。

updateValueFactory
Func<TKey,TValue,TArg,TValue>

キーの既存の値に基づいて既存のキーの新しい値を生成するために使用される関数。

factoryArgument
TArg

addValueFactoryupdateValueFactoryに渡す引数。

返品

TValue

キーの新しい値。 これは、 addValueFactory の結果 (キーが存在しない場合) または updateValueFactory の結果 (キーが存在する場合) のいずれかになります。

例外

keyaddValueFactory、または updateValueFactory は null 参照です (Visual Basic では Nothing)。

ディクショナリに含まれる要素が多すぎます。

注釈

異なるスレッドで AddOrUpdate を同時に呼び出す場合、 addValueFactory は複数回呼び出すことができますが、そのキーと値のペアが呼び出しごとにディクショナリに追加されない可能性があります。

ディクショナリに対する変更および書き込み操作の場合、 ConcurrentDictionary<TKey,TValue> は細かいロックを使用してスレッド の安全性を確保します。 (ディクショナリに対する読み取り操作は、ロックフリーの方法で実行されます)。 addValueFactory および updateValueFactory デリゲートは、値が期待どおりに追加または更新されたことを確認するために複数回実行できます。 ただし、ロックの下で不明なコードを実行することによって発生する可能性のある問題を回避するために、ロックの外部で呼び出されます。 したがって、 AddOrUpdate は、 ConcurrentDictionary<TKey,TValue> クラスに対する他のすべての操作に関してアトミックではありません。

適用対象