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
複数回呼び出すことができますが、ディクショナリに追加されるキーと値のペアは 1 つだけです。
戻り値は、ディクショナリ内のキーの存在と、 が呼び出された後 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
複数回呼び出すことができますが、ディクショナリに追加されるキーと値のペアは 1 つだけです。
戻り値は、ディクショナリ内のキーの存在と、 が呼び出された後 GetOrAdd に別のスレッドによってキー/値が挿入されるかどうかによって異なりますが、その前に valueFactory
値が生成されます。
シナリオ | 戻り値 |
---|---|
キーは既にディクショナリにあります。 | 既存の値が返されます。 |
キーがディクショナリにありません。 valueFactory は値を生成します。 キーの再確認時に、キーが見つかりません。 |
キー/値がディクショナリに挿入され、値が返されます。 |
キーがディクショナリにありません。 valueFactory は値を生成します。 値の生成中 valueFactory に、別のスレッドによってキーの値が挿入されます。 を実行した後 valueFactory 、キーを再チェックすると、他のスレッドによって挿入されたキーが見つかります。 |
他のスレッドによって挿入された値が返されます。 |
適用対象
.NET