ConcurrentDictionary<TKey,TValue>.AddOrUpdate 메서드
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
키가 아직 없는 경우 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>)
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
지정된 함수를 사용하여 키가 아직 없는 경우 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>
키의 기존 값을 기준으로 기존 키의 새 값을 생성하는 데 사용되는 함수입니다.
반환
키의 새 값입니다. addValueFactory
가 발생(키가 없는 경우)하거나 updateValueFactory
가 발생(키가 있는 경우)합니다.
예외
key
, addValueFactory
또는 updateValueFactory
가 null
입니다.
사전에 너무 많은 요소가 포함되어 있습니다.
설명
다른 스레드에서 동시에 를 호출 AddOrUpdate 하는 경우 는 addValueFactory
여러 번 호출될 수 있지만 해당 키/값 쌍은 모든 호출에 대해 사전에 추가되지 않을 수 있습니다.
사전에 대한 수정 및 쓰기 작업의 경우 는 ConcurrentDictionary<TKey,TValue> 세분화된 잠금을 사용하여 스레드 안전을 보장합니다(사전에 대한 읽기 작업은 잠금이 없는 방식으로 수행됨). addValueFactory
및 updateValueFactory
대리자를 여러 번 실행하여 값이 예상대로 추가되거나 업데이트되었는지 확인할 수 있습니다. 그러나 잠금에서 알 수 없는 코드를 실행하여 발생할 수 있는 문제를 방지하기 위해 잠금 외부에서 호출됩니다. 따라서 는 AddOrUpdate 클래스의 다른 모든 연산 ConcurrentDictionary<TKey,TValue> 과 관련하여 원자적이지 않습니다.
추가 정보
적용 대상
AddOrUpdate(TKey, TValue, Func<TKey,TValue,TValue>)
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
키가 아직 없는 경우 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>
키의 기존 값을 기준으로 기존 키의 새 값을 생성하는 데 사용되는 함수입니다.
반환
키의 새 값입니다. addValue
가 발생(키가 없는 경우)하거나 updateValueFactory
가 발생(키가 있는 경우)합니다.
예외
key
또는 updateValueFactory
가 null
인 경우
사전에 너무 많은 요소가 포함되어 있습니다.
예제
다음 코드 예제에서는 를 초기화하는 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)
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
- Source:
- ConcurrentDictionary.cs
지정된 함수와 인수를 사용하여 키가 아직 없는 경우 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
및 updateValueFactory
에 전달할 addValueFactory
인수의 형식입니다.
매개 변수
- key
- TKey
추가하거나 값을 업데이트해야 하는 키입니다.
- addValueFactory
- Func<TKey,TArg,TValue>
없는 키에 대한 값을 생성하는 데 사용되는 함수입니다.
- updateValueFactory
- Func<TKey,TValue,TArg,TValue>
키의 기존 값을 기준으로 기존 키의 새 값을 생성하는 데 사용되는 함수입니다.
- factoryArgument
- TArg
addValueFactory
및 updateValueFactory
에 전달할 인수입니다.
반환
키의 새 값입니다. addValueFactory
가 발생(키가 없는 경우)하거나 updateValueFactory
가 발생(키가 있는 경우)합니다.
예외
key
, addValueFactory
또는 updateValueFactory
가 null 참조(Visual Basic의 경우 Nothing)인 경우
사전에 너무 많은 요소가 포함되어 있습니다.
설명
다른 스레드에서 동시에 를 호출 AddOrUpdate 하는 경우 는 addValueFactory
여러 번 호출될 수 있지만 해당 키/값 쌍은 모든 호출에 대해 사전에 추가되지 않을 수 있습니다.
사전에 대한 수정 및 쓰기 작업의 경우 는 ConcurrentDictionary<TKey,TValue> 세분화된 잠금을 사용하여 스레드 안전을 보장합니다. (사전에 대한 읽기 작업은 잠금이 없는 방식으로 수행됩니다.) addValueFactory
및 updateValueFactory
대리자를 여러 번 실행하여 값이 예상대로 추가되거나 업데이트되었는지 확인할 수 있습니다. 그러나 잠금에서 알 수 없는 코드를 실행하여 발생할 수 있는 문제를 방지하기 위해 잠금 외부에서 호출됩니다. 따라서 는 AddOrUpdate 클래스의 다른 모든 연산 ConcurrentDictionary<TKey,TValue> 과 관련하여 원자적이지 않습니다.
적용 대상
.NET