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>)

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

키의 값입니다. 사전에 키가 있는 경우 키의 기존 값이고, 사전에 키가 없는 경우 새 값입니다.

예외

key 또는 valueFactorynull인 경우

사전에 너무 많은 요소가 포함되어 있습니다.

설명

사전에 ConcurrentDictionary<TKey,TValue> 대한 수정 및 쓰기 작업의 경우 는 세분화된 잠금을 사용하여 스레드 안전을 보장합니다. (사전에서 읽기 작업은 잠금 없는 방식으로 수행됩니다.) 그러나 잠금에서 valueFactory 알 수 없는 코드를 실행하여 발생할 수 있는 문제를 방지하기 위해 대리자를 잠금 외부에서 호출합니다. 따라서 는 GetOrAdd 클래스의 다른 모든 연산 ConcurrentDictionary<TKey,TValue> 과 관련하여 원자적이지 않습니다.

값을 생성하는 동안 valueFactory 다른 스레드에서 키/값을 삽입할 수 있으므로 실행되었다고 해서 valueFactory 생성된 값이 사전에 삽입되어 반환된다는 것을 신뢰할 수 없습니다. 다른 스레드에서 동시에 호출 GetOrAdd 하는 경우 를 valueFactory 여러 번 호출할 수 있지만 하나의 키/값 쌍만 사전에 추가됩니다.

반환 값은 사전의 키 존재 여부와 가 호출된 후 GetOrAdd 다른 스레드에서 키/값을 삽입할지와 값을 생성하기 전에 valueFactory 삽입되는지 여부에 따라 달라집니다.

시나리오 반환 값
키가 이미 사전에 있습니다. 기존 값이 반환됩니다.
키가 사전에 없습니다. valueFactory 는 값을 생성합니다. 키를 다시 검사할 때 키를 찾을 수 없습니다. 키/값이 사전에 삽입되고 값이 반환됩니다.
키가 사전에 없습니다. valueFactory 는 값을 생성합니다. 값을 생성하는 동안 valueFactory 다른 스레드가 키에 대한 값을 삽입합니다. valueFactory 를 실행하고 키를 다시 검사하면 다른 스레드에서 삽입한 키를 찾습니다. 다른 스레드에서 삽입한 값이 반환됩니다.

추가 정보

적용 대상

GetOrAdd(TKey, TValue)

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

키의 값입니다. 사전에 키가 있는 경우 키의 기존 값이고, 사전에 키가 없는 경우 새 값입니다.

예외

key이(가) null인 경우

사전에 너무 많은 요소가 포함되어 있습니다.

추가 정보

적용 대상

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

Source:
ConcurrentDictionary.cs
Source:
ConcurrentDictionary.cs
Source:
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 생성된 값이 사전에 삽입되어 반환된다는 것을 신뢰할 수 없습니다. 다른 스레드에서 동시에 호출 GetOrAdd 하는 경우 를 valueFactory 여러 번 호출할 수 있지만 하나의 키/값 쌍만 사전에 추가됩니다.

반환 값은 사전의 키 존재 여부와 가 호출된 후 GetOrAdd 다른 스레드에서 키/값을 삽입할지와 값을 생성하기 전에 valueFactory 삽입되는지 여부에 따라 달라집니다.

시나리오 반환 값
키가 이미 사전에 있습니다. 기존 값이 반환됩니다.
키가 사전에 없습니다. valueFactory 는 값을 생성합니다. 키를 다시 검사할 때 키를 찾을 수 없습니다. 키/값이 사전에 삽입되고 값이 반환됩니다.
키가 사전에 없습니다. valueFactory 는 값을 생성합니다. 값을 생성하는 동안 valueFactory 다른 스레드가 키에 대한 값을 삽입합니다. valueFactory 를 실행하고 키를 다시 검사하면 다른 스레드에서 삽입한 키를 찾습니다. 다른 스레드에서 삽입한 값이 반환됩니다.

적용 대상