ConcurrentDictionary<TKey,TValue>.GetOrAdd Metoda
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Pokud klíč ještě neexistuje, přidá do ConcurrentDictionary<TKey,TValue> páru klíč-hodnota. Vrátí novou hodnotu nebo existující hodnotu, pokud klíč již existuje.
Přetížení
GetOrAdd(TKey, Func<TKey,TValue>) |
Pokud klíč ještě neexistuje, přidá dvojici klíč-hodnota do parametru ConcurrentDictionary<TKey,TValue> pomocí zadané funkce. Vrátí novou hodnotu nebo existující hodnotu, pokud klíč existuje. |
GetOrAdd(TKey, TValue) |
Pokud klíč ještě neexistuje, přidá do ConcurrentDictionary<TKey,TValue> páru klíč-hodnota. Vrátí novou hodnotu nebo existující hodnotu, pokud klíč existuje. |
GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg) |
Přidá dvojici klíč/hodnota do objektu ConcurrentDictionary<TKey,TValue> pomocí zadané funkce a argumentu, pokud klíč ještě neexistuje, nebo vrátí existující hodnotu, pokud klíč existuje. |
Příklady
Následující příklad ukazuje, jak volat metodu 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>)
- Zdroj:
- ConcurrentDictionary.cs
- Zdroj:
- ConcurrentDictionary.cs
- Zdroj:
- ConcurrentDictionary.cs
Pokud klíč ještě neexistuje, přidá dvojici klíč-hodnota do parametru ConcurrentDictionary<TKey,TValue> pomocí zadané funkce. Vrátí novou hodnotu nebo existující hodnotu, pokud klíč existuje.
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
Parametry
- key
- TKey
Klíč elementu, který chcete přidat.
- valueFactory
- Func<TKey,TValue>
Funkce, která slouží k vygenerování hodnoty klíče.
Návraty
Hodnota klíče. Bude to buď existující hodnota klíče, pokud je klíč již ve slovníku, nebo nová hodnota, pokud klíč nebyl ve slovníku.
Výjimky
key
nebo valueFactory
je null
.
Slovník obsahuje příliš mnoho prvků.
Poznámky
Pro úpravy a operace zápisu do slovníku ConcurrentDictionary<TKey,TValue> používá jemně odstupňované zamykání, které zajišťuje bezpečnost vláken. (Operace čtení ve slovníku se provádějí bez uzamčení.) Delegát je však volána mimo zámky, valueFactory
aby se zabránilo problémům, které mohou nastat při spuštění neznámého kódu pod zámkem. GetOrAdd Proto není atomický, pokud jde o všechny ostatní operace ve ConcurrentDictionary<TKey,TValue> třídě.
Vzhledem k tomu, že klíč/hodnota může být vložen do jiného vlákna, zatímco valueFactory
generuje hodnotu, nemůžete důvěřovat tomu, že jen proto, že valueFactory
je spuštěn, bude jeho vytvořená hodnota vložena do slovníku a vrácena. Pokud voláte GetOrAdd současně v různých vláknech, valueFactory
může být volána vícekrát, ale pouze jeden pár klíč/hodnota bude přidán do slovníku.
Vrácená hodnota závisí na přítomnosti klíče ve slovníku a na tom, jestli je klíč/hodnota vložena do jiného vlákna po GetOrAdd zavolání, ale před valueFactory
vygenerováním hodnoty:
Scenario | Vrácená hodnota |
---|---|
Klíč je již ve slovníku. | Vrátí se existující hodnota. |
Klíč není ve slovníku. valueFactory generuje hodnotu. Při opětovné kontrole klíče nebyl nalezen žádný klíč. |
Klíč/hodnota se vloží do slovníku a vrátí se hodnota. |
Klíč není ve slovníku. valueFactory generuje hodnotu. Zatímco valueFactory generuje hodnotu, jiné vlákno vloží hodnotu klíče. Po valueFactory provedení a opětovné kontrole klíče se najde klíč vložený druhým vláknem. |
Vrátí se hodnota vložená druhým vláknem. |
Viz také
- Kolekce bezpečné pro přístup z více vláken
- Postupy: Přidávání a odebírání položek v ConcurrentDictionary
Platí pro
GetOrAdd(TKey, TValue)
- Zdroj:
- ConcurrentDictionary.cs
- Zdroj:
- ConcurrentDictionary.cs
- Zdroj:
- ConcurrentDictionary.cs
Pokud klíč ještě neexistuje, přidá do ConcurrentDictionary<TKey,TValue> páru klíč-hodnota. Vrátí novou hodnotu nebo existující hodnotu, pokud klíč existuje.
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
Parametry
- key
- TKey
Klíč elementu, který chcete přidat.
- value
- TValue
Hodnota, která se má přidat, pokud klíč ještě neexistuje.
Návraty
Hodnota klíče. Bude to buď existující hodnota klíče, pokud je klíč již ve slovníku, nebo nová hodnota, pokud klíč nebyl ve slovníku.
Výjimky
key
je null
.
Slovník obsahuje příliš mnoho prvků.
Viz také
- Kolekce bezpečné pro přístup z více vláken
- Postupy: Přidávání a odebírání položek v ConcurrentDictionary
Platí pro
GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg)
- Zdroj:
- ConcurrentDictionary.cs
- Zdroj:
- ConcurrentDictionary.cs
- Zdroj:
- ConcurrentDictionary.cs
Přidá dvojici klíč/hodnota do objektu ConcurrentDictionary<TKey,TValue> pomocí zadané funkce a argumentu, pokud klíč ještě neexistuje, nebo vrátí existující hodnotu, pokud klíč existuje.
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
Parametry typu
- TArg
Typ argumentu, který se má předat do valueFactory
.
Parametry
- key
- TKey
Klíč elementu, který chcete přidat.
- valueFactory
- Func<TKey,TArg,TValue>
Funkce, která slouží k vygenerování hodnoty klíče.
- factoryArgument
- TArg
Hodnota argumentu, která se má předat do valueFactory
.
Návraty
Hodnota klíče. Bude to buď existující hodnota klíče, pokud je klíč již ve slovníku, nebo nová hodnota, pokud klíč nebyl ve slovníku.
Výjimky
key
null
je odkaz (Nothing v jazyce Visual Basic).
Slovník obsahuje příliš mnoho prvků.
Poznámky
Pro úpravy a operace zápisu do slovníku ConcurrentDictionary<TKey,TValue> používá jemně odstupňované zamykání, které zajišťuje bezpečnost vláken. (Operace čtení ve slovníku se provádějí bez uzamčení.) Delegát je však volána mimo zámky, valueFactory
aby se zabránilo problémům, které mohou nastat při spuštění neznámého kódu pod zámkem. GetOrAdd Proto není atomický, pokud jde o všechny ostatní operace ve ConcurrentDictionary<TKey,TValue> třídě.
Vzhledem k tomu, že klíč/hodnota může být vložen do jiného vlákna, zatímco valueFactory
generuje hodnotu, nemůžete důvěřovat tomu, že jen proto, že valueFactory
je spuštěn, bude jeho vytvořená hodnota vložena do slovníku a vrácena. Pokud voláte GetOrAdd současně v různých vláknech, valueFactory
může být volána vícekrát, ale pouze jeden pár klíč/hodnota bude přidán do slovníku.
Vrácená hodnota závisí na přítomnosti klíče ve slovníku a na tom, jestli je klíč/hodnota vložena do jiného vlákna po GetOrAdd zavolání, ale před valueFactory
vygenerováním hodnoty:
Scenario | Vrácená hodnota |
---|---|
Klíč je již ve slovníku. | Vrátí se existující hodnota. |
Klíč není ve slovníku. valueFactory generuje hodnotu. Při opětovné kontrole klíče nebyl nalezen žádný klíč. |
Klíč/hodnota se vloží do slovníku a vrátí se hodnota. |
Klíč není ve slovníku. valueFactory generuje hodnotu. Zatímco valueFactory generuje hodnotu, jiné vlákno vloží hodnotu klíče. Po valueFactory provedení a opětovné kontrole klíče se najde klíč vložený druhým vláknem. |
Vrátí se hodnota vložená druhým vláknem. |