ConcurrentDictionary<TKey,TValue>.GetOrAdd 메서드

정의

키가 아직 없는 경우 키/값 쌍 ConcurrentDictionary<TKey,TValue> 을 추가합니다. 새 값을 반환하거나 키가 이미 있는 경우 기존 값을 반환합니다.

오버로드

Name Description
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>

키 값을 생성하는 데 사용되는 함수입니다.

반품

TValue

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

예외

key 또는 valueFactory .입니다 null.

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

설명

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

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

반환 값은 사전에 키가 있는지 여부와 호출된 후 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

키가 아직 없는 경우 추가할 값입니다.

반품

TValue

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

예외

keynull입니다.

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

추가 정보

적용 대상

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.

반품

TValue

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

예외

keynull 참조입니다(Visual Basic 없음).

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

설명

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

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

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

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

적용 대상