16 [DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<, >))]
17 [DebuggerDisplay(
"Count = {Count}")]
18 [__DynamicallyInvokable]
19 [HostProtection(
SecurityAction.LinkDemand, Synchronization =
true, ExternalThreading =
true)]
20 public class ConcurrentDictionary<TKey, TValue> :
IDictionary<TKey, TValue>,
ICollection<KeyValuePair<TKey, TValue>>,
IEnumerable<KeyValuePair<TKey, TValue>>,
IEnumerable,
IDictionary,
ICollection,
IReadOnlyDictionary<TKey, TValue>,
IReadOnlyCollection<KeyValuePair<TKey, TValue>>
24 internal readonly Node[] m_buckets;
26 internal readonly
object[] m_locks;
28 internal volatile int[] m_countPerLock;
36 m_countPerLock = countPerLock;
37 m_comparer = comparer;
45 internal TValue m_value;
47 internal volatile Node m_next;
49 internal int m_hashcode;
51 internal Node(TKey key, TValue value,
int hashcode, Node next)
56 m_hashcode = hashcode;
66 public object Key => m_enumerator.
Current.Key;
68 public object Value => m_enumerator.
Current.Value;
70 public object Current => Entry;
74 m_enumerator = dictionary.GetEnumerator();
77 public bool MoveNext()
89 private volatile Tables m_tables;
94 private readonly
bool m_growLockArray;
97 private int m_keyRehashCount;
100 private int m_budget;
104 private int m_serializationConcurrencyLevel;
106 private int m_serializationCapacity;
108 private const int DEFAULT_CONCURRENCY_MULTIPLIER = 4;
110 private const int DEFAULT_CAPACITY = 31;
112 private const int MAX_LOCK_NUMBER = 1024;
114 private static readonly
bool s_isValueWriteAtomic = IsValueWriteAtomic();
122 [__DynamicallyInvokable]
123 public TValue
this[TKey key]
125 [__DynamicallyInvokable]
134 [__DynamicallyInvokable]
141 TryAddInternal(key, value, updateIfExists:
true, acquireLock:
true, out TValue _);
148 [__DynamicallyInvokable]
151 [__DynamicallyInvokable]
155 int locksAcquired = 0;
158 AcquireAllLocks(ref locksAcquired);
159 for (
int i = 0; i < m_tables.m_countPerLock.Length; i++)
161 num += m_tables.m_countPerLock[i];
167 ReleaseLocks(0, locksAcquired);
175 [__DynamicallyInvokable]
178 [__DynamicallyInvokable]
181 int locksAcquired = 0;
184 AcquireAllLocks(ref locksAcquired);
185 for (
int i = 0; i < m_tables.m_countPerLock.Length; i++)
187 if (m_tables.m_countPerLock[i] != 0)
195 ReleaseLocks(0, locksAcquired);
203 [__DynamicallyInvokable]
206 [__DynamicallyInvokable]
213 [__DynamicallyInvokable]
216 [__DynamicallyInvokable]
225 [__DynamicallyInvokable]
228 [__DynamicallyInvokable]
235 [__DynamicallyInvokable]
238 [__DynamicallyInvokable]
245 [__DynamicallyInvokable]
248 [__DynamicallyInvokable]
258 [__DynamicallyInvokable]
261 [__DynamicallyInvokable]
271 [__DynamicallyInvokable]
274 [__DynamicallyInvokable]
283 [__DynamicallyInvokable]
286 [__DynamicallyInvokable]
295 [__DynamicallyInvokable]
298 [__DynamicallyInvokable]
311 [__DynamicallyInvokable]
314 [__DynamicallyInvokable]
319 throw new ArgumentNullException(
"key");
321 if (key is TKey &&
TryGetValue((TKey)key, out TValue value))
327 [__DynamicallyInvokable]
332 throw new ArgumentNullException(
"key");
336 throw new ArgumentException(GetResource(
"ConcurrentDictionary_TypeOfKeyIncorrect"));
338 if (!(value is TValue))
340 throw new ArgumentException(GetResource(
"ConcurrentDictionary_TypeOfValueIncorrect"));
342 this[(TKey)key] = (TValue)value;
349 [__DynamicallyInvokable]
352 [__DynamicallyInvokable]
362 [__DynamicallyInvokable]
365 [__DynamicallyInvokable]
368 throw new NotSupportedException(Environment.GetResourceString(
"ConcurrentCollection_SyncRoot_NotSupported"));
372 private static int DefaultConcurrencyLevel => 4 * PlatformHelper.ProcessorCount;
374 private static bool IsValueWriteAtomic()
376 Type typeFromHandle = typeof(TValue);
377 bool flag = typeFromHandle.IsClass || typeFromHandle == typeof(
bool) || typeFromHandle == typeof(
char) || typeFromHandle == typeof(
byte) || typeFromHandle == typeof(sbyte) || typeFromHandle == typeof(
short) || typeFromHandle == typeof(ushort) || typeFromHandle == typeof(
int) || typeFromHandle == typeof(uint) || typeFromHandle == typeof(
float);
378 if (!flag && IntPtr.Size == 8)
380 flag |= (typeFromHandle == typeof(
double) || typeFromHandle == typeof(
long));
386 [__DynamicallyInvokable]
398 [__DynamicallyInvokable]
410 [__DynamicallyInvokable]
420 [__DynamicallyInvokable]
422 : this(DefaultConcurrencyLevel, 31, growLockArray: true, comparer)
431 [__DynamicallyInvokable]
435 if (collection ==
null)
439 InitializeFromCollection(collection);
452 [__DynamicallyInvokable]
454 : this(concurrencyLevel, 31, growLockArray: false, comparer)
456 if (collection ==
null)
460 if (comparer ==
null)
464 InitializeFromCollection(collection);
471 if (item.Key ==
null)
475 if (!TryAddInternal(item.Key, item.Value, updateIfExists:
false, acquireLock:
false, out TValue _))
477 throw new ArgumentException(GetResource(
"ConcurrentDictionary_SourceContainsDuplicateKeys"));
482 m_budget = m_tables.m_buckets.Length / m_tables.m_locks.Length;
494 [__DynamicallyInvokable]
496 : this(concurrencyLevel, capacity, growLockArray: false, comparer)
502 if (concurrencyLevel < 1)
510 if (comparer ==
null)
514 if (capacity < concurrencyLevel)
516 capacity = concurrencyLevel;
518 object[] array =
new object[concurrencyLevel];
519 for (
int i = 0; i < array.Length; i++)
521 array[i] =
new object();
523 int[] countPerLock =
new int[array.Length];
525 m_tables =
new Tables(array2, array, countPerLock, comparer);
526 m_growLockArray = growLockArray;
527 m_budget = array2.Length / array.Length;
538 [__DynamicallyInvokable]
539 public bool TryAdd(TKey key, TValue value)
545 TValue resultingValue;
546 return TryAddInternal(key, value, updateIfExists:
false, acquireLock:
true, out resultingValue);
555 [__DynamicallyInvokable]
573 [__DynamicallyInvokable]
580 return TryRemoveInternal(key, out value, matchValue:
false,
default(TValue));
583 private bool TryRemoveInternal(TKey key, out TValue value,
bool matchValue, TValue oldValue)
587 Tables tables = m_tables;
589 GetBucketAndLockNo(comparer.
GetHashCode(key), out
int bucketNo, out
int lockNo, tables.m_buckets.Length, tables.m_locks.Length);
590 lock (tables.m_locks[lockNo])
592 if (tables == m_tables)
595 for (Node node2 = tables.m_buckets[bucketNo]; node2 !=
null; node2 = node2.m_next)
597 if (comparer.
Equals(node2.m_key, key))
601 value =
default(TValue);
606 Volatile.
Write(ref tables.m_buckets[bucketNo], node2.m_next);
610 node.m_next = node2.m_next;
612 value = node2.m_value;
613 tables.m_countPerLock[lockNo]--;
622 value =
default(TValue);
633 [__DynamicallyInvokable]
640 Tables tables = m_tables;
642 GetBucketAndLockNo(comparer.
GetHashCode(key), out
int bucketNo, out
int _, tables.m_buckets.Length, tables.m_locks.Length);
643 for (Node node =
Volatile.
Read(ref tables.m_buckets[bucketNo]); node !=
null; node = node.m_next)
645 if (comparer.
Equals(node.m_key, key))
647 value = node.m_value;
651 value =
default(TValue);
663 [__DynamicallyInvokable]
664 public bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue)
673 Tables tables = m_tables;
676 GetBucketAndLockNo(hashCode, out
int bucketNo, out
int lockNo, tables.m_buckets.Length, tables.m_locks.Length);
677 lock (tables.m_locks[lockNo])
679 if (tables == m_tables)
682 for (Node node2 = tables.m_buckets[bucketNo]; node2 !=
null; node2 = node2.m_next)
684 if (comparer.
Equals(node2.m_key, key))
686 if (@
default.Equals(node2.m_value, comparisonValue))
688 if (s_isValueWriteAtomic)
690 node2.m_value = newValue;
694 Node node3 =
new Node(node2.m_key, newValue, hashCode, node2.m_next);
697 tables.m_buckets[bucketNo] = node3;
717 [__DynamicallyInvokable]
720 int locksAcquired = 0;
723 AcquireAllLocks(ref locksAcquired);
724 Tables tables = m_tables =
new Tables(
new Node[31], m_tables.m_locks,
new int[m_tables.m_countPerLock.Length], m_tables.m_comparer);
725 m_budget =
Math.
Max(1, tables.m_buckets.Length / tables.m_locks.Length);
729 ReleaseLocks(0, locksAcquired);
733 [__DynamicallyInvokable]
744 int locksAcquired = 0;
747 AcquireAllLocks(ref locksAcquired);
749 for (
int i = 0; i < m_tables.m_locks.Length; i++)
755 num += m_tables.m_countPerLock[i];
757 if (array.Length - num < index || num < 0)
759 throw new ArgumentException(GetResource(
"ConcurrentDictionary_ArrayNotLargeEnough"));
761 CopyToPairs(array, index);
765 ReleaseLocks(0, locksAcquired);
771 [__DynamicallyInvokable]
774 int locksAcquired = 0;
779 AcquireAllLocks(ref locksAcquired);
781 for (
int i = 0; i < m_tables.m_locks.Length; i++)
783 num += m_tables.m_countPerLock[i];
786 CopyToPairs(array, 0);
791 ReleaseLocks(0, locksAcquired);
798 Node[] buckets = m_tables.m_buckets;
799 for (
int i = 0; i < buckets.Length; i++)
801 for (Node node = buckets[i]; node !=
null; node = node.m_next)
809 private void CopyToEntries(DictionaryEntry[] array,
int index)
811 Node[] buckets = m_tables.m_buckets;
812 for (
int i = 0; i < buckets.Length; i++)
814 for (Node node = buckets[i]; node !=
null; node = node.m_next)
816 array[index] =
new DictionaryEntry(node.m_key, node.m_value);
822 private void CopyToObjects(
object[] array,
int index)
824 Node[] buckets = m_tables.m_buckets;
825 for (
int i = 0; i < buckets.Length; i++)
827 for (Node node = buckets[i]; node !=
null; node = node.m_next)
837 [__DynamicallyInvokable]
840 Node[] buckets = m_tables.m_buckets;
841 for (
int i = 0; i < buckets.Length; i++)
843 for (Node current =
Volatile.
Read(ref buckets[i]); current !=
null; current = current.m_next)
850 private bool TryAddInternal(TKey key, TValue value,
bool updateIfExists,
bool acquireLock, out TValue resultingValue)
859 comparer = tables.m_comparer;
861 GetBucketAndLockNo(hashCode, out
int bucketNo, out
int lockNo, tables.m_buckets.Length, tables.m_locks.Length);
863 bool lockTaken =
false;
871 if (tables == m_tables)
875 for (Node node2 = tables.m_buckets[bucketNo]; node2 !=
null; node2 = node2.m_next)
877 if (comparer.
Equals(node2.m_key, key))
881 if (s_isValueWriteAtomic)
883 node2.m_value = value;
887 Node node3 =
new Node(node2.m_key, value, hashCode, node2.m_next);
890 tables.m_buckets[bucketNo] = node3;
897 resultingValue = value;
901 resultingValue = node2.m_value;
908 if (num > 100 && HashHelpers.IsWellKnownEqualityComparer(comparer))
913 Volatile.
Write(ref tables.m_buckets[bucketNo],
new Node(key, value, hashCode, tables.m_buckets[bucketNo]));
916 tables.m_countPerLock[lockNo]++;
917 if (tables.m_countPerLock[lockNo] > m_budget)
937 GrowTable(tables, (
IEqualityComparer<TKey>)HashHelpers.GetRandomizedEqualityComparer(comparer), regenerateHashKeys:
true, m_keyRehashCount);
941 GrowTable(tables, tables.m_comparer, regenerateHashKeys:
false, m_keyRehashCount);
944 resultingValue = value;
955 [__DynamicallyInvokable]
956 public TValue
GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
962 if (valueFactory ==
null)
970 TryAddInternal(key, valueFactory(key), updateIfExists:
false, acquireLock:
true, out value);
981 [__DynamicallyInvokable]
988 TryAddInternal(key, value, updateIfExists:
false, acquireLock:
true, out TValue resultingValue);
989 return resultingValue;
1000 [__DynamicallyInvokable]
1001 public TValue
AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
1007 if (addValueFactory ==
null)
1011 if (updateValueFactory ==
null)
1015 TValue resultingValue;
1020 TValue val = updateValueFactory(key, value);
1028 TValue val = addValueFactory(key);
1029 if (TryAddInternal(key, val, updateIfExists:
false, acquireLock:
true, out resultingValue))
1035 return resultingValue;
1046 [__DynamicallyInvokable]
1047 public TValue
AddOrUpdate(TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory)
1053 if (updateValueFactory ==
null)
1057 TValue resultingValue;
1062 TValue val = updateValueFactory(key, value);
1068 else if (TryAddInternal(key, addValue, updateIfExists:
false, acquireLock:
true, out resultingValue))
1073 return resultingValue;
1076 [__DynamicallyInvokable]
1081 throw new ArgumentException(GetResource(
"ConcurrentDictionary_KeyAlreadyExisted"));
1085 [__DynamicallyInvokable]
1092 [__DynamicallyInvokable]
1098 [__DynamicallyInvokable]
1108 [__DynamicallyInvokable]
1111 if (keyValuePair.
Key ==
null)
1113 throw new ArgumentNullException(GetResource(
"ConcurrentDictionary_ItemKeyIsNull"));
1116 return TryRemoveInternal(keyValuePair.
Key, out value, matchValue:
true, keyValuePair.
Value);
1121 [__DynamicallyInvokable]
1136 [__DynamicallyInvokable]
1141 throw new ArgumentNullException(
"key");
1145 throw new ArgumentException(GetResource(
"ConcurrentDictionary_TypeOfKeyIncorrect"));
1150 value2 = (TValue)value;
1152 catch (InvalidCastException)
1154 throw new ArgumentException(GetResource(
"ConcurrentDictionary_TypeOfValueIncorrect"));
1165 [__DynamicallyInvokable]
1170 throw new ArgumentNullException(
"key");
1181 [__DynamicallyInvokable]
1184 return new DictionaryEnumerator(
this);
1191 [__DynamicallyInvokable]
1196 throw new ArgumentNullException(
"key");
1213 [__DynamicallyInvokable]
1218 throw new ArgumentNullException(
"array");
1222 throw new ArgumentOutOfRangeException(
"index", GetResource(
"ConcurrentDictionary_IndexIsNegative"));
1224 int locksAcquired = 0;
1227 AcquireAllLocks(ref locksAcquired);
1228 Tables tables = m_tables;
1230 for (
int i = 0; i < tables.m_locks.Length; i++)
1236 num += tables.m_countPerLock[i];
1238 if (array.Length - num < index || num < 0)
1240 throw new ArgumentException(GetResource(
"ConcurrentDictionary_ArrayNotLargeEnough"));
1245 CopyToPairs(array2, index);
1249 DictionaryEntry[] array3 = array as DictionaryEntry[];
1252 CopyToEntries(array3, index);
1256 object[] array4 = array as
object[];
1259 throw new ArgumentException(GetResource(
"ConcurrentDictionary_ArrayIncorrectType"),
"array");
1261 CopyToObjects(array4, index);
1267 ReleaseLocks(0, locksAcquired);
1271 private void GrowTable(Tables tables,
IEqualityComparer<TKey> newComparer,
bool regenerateHashKeys,
int rehashCount)
1273 int locksAcquired = 0;
1276 AcquireLocks(0, 1, ref locksAcquired);
1277 if (regenerateHashKeys && rehashCount == m_keyRehashCount)
1282 if (tables == m_tables)
1285 for (
int i = 0; i < tables.m_countPerLock.Length; i++)
1287 num += tables.m_countPerLock[i];
1289 if (num >= tables.m_buckets.Length / 4)
1293 m_budget = 2 * m_budget;
1296 m_budget =
int.MaxValue;
1305 for (j = checked(tables.m_buckets.Length * 2 + 1); j % 3 == 0 || j % 5 == 0 || j % 7 == 0; j = checked(j + 2))
1313 catch (OverflowException)
1320 m_budget =
int.MaxValue;
1322 AcquireLocks(1, tables.m_locks.Length, ref locksAcquired);
1323 object[] array = tables.m_locks;
1324 if (m_growLockArray && tables.m_locks.Length < 1024)
1326 array =
new object[tables.m_locks.Length * 2];
1327 Array.Copy(tables.m_locks, array, tables.m_locks.Length);
1328 for (
int k = tables.m_locks.Length; k < array.Length; k++)
1330 array[k] =
new object();
1334 int[] array3 =
new int[array.Length];
1335 for (
int l = 0; l < tables.m_buckets.Length; l++)
1340 for (Node node = tables.m_buckets[l]; node !=
null; node = next)
1343 int hashcode = node.m_hashcode;
1344 if (regenerateHashKeys)
1348 GetBucketAndLockNo(hashcode, out
int bucketNo, out
int lockNo, array2.Length, array.Length);
1349 array2[bucketNo] =
new Node(node.m_key, node.m_value, hashcode, array2[bucketNo]);
1354 if (regenerateHashKeys)
1358 m_budget = Math.Max(1, array2.Length / array.Length);
1359 m_tables =
new Tables(array2, array, array3, newComparer);
1364 ReleaseLocks(0, locksAcquired);
1368 private void GetBucketAndLockNo(
int hashcode, out
int bucketNo, out
int lockNo,
int bucketCount,
int lockCount)
1370 bucketNo = (hashcode &
int.MaxValue) % bucketCount;
1371 lockNo = bucketNo % lockCount;
1374 private void AcquireAllLocks(ref
int locksAcquired)
1376 if (CDSCollectionETWBCLProvider.Log.IsEnabled())
1378 CDSCollectionETWBCLProvider.Log.ConcurrentDictionary_AcquiringAllLocks(m_tables.m_buckets.Length);
1380 AcquireLocks(0, 1, ref locksAcquired);
1381 AcquireLocks(1, m_tables.m_locks.Length, ref locksAcquired);
1384 private void AcquireLocks(
int fromInclusive,
int toExclusive, ref
int locksAcquired)
1386 object[] locks = m_tables.m_locks;
1387 for (
int i = fromInclusive; i < toExclusive; i++)
1389 bool lockTaken =
false;
1404 private void ReleaseLocks(
int fromInclusive,
int toExclusive)
1406 for (
int i = fromInclusive; i < toExclusive; i++)
1414 int locksAcquired = 0;
1417 AcquireAllLocks(ref locksAcquired);
1419 for (
int i = 0; i < m_tables.m_buckets.Length; i++)
1421 for (Node node = m_tables.m_buckets[i]; node !=
null; node = node.m_next)
1423 list.Add(node.m_key);
1430 ReleaseLocks(0, locksAcquired);
1436 int locksAcquired = 0;
1439 AcquireAllLocks(ref locksAcquired);
1441 for (
int i = 0; i < m_tables.m_buckets.Length; i++)
1443 for (Node node = m_tables.m_buckets[i]; node !=
null; node = node.m_next)
1445 list.Add(node.m_value);
1452 ReleaseLocks(0, locksAcquired);
1457 private void Assert(
bool condition)
1461 private string GetResource(
string key)
1463 return Environment.GetResourceString(key);
1469 Tables tables = m_tables;
1470 m_serializationArray =
ToArray();
1471 m_serializationConcurrencyLevel = tables.m_locks.Length;
1472 m_serializationCapacity = tables.m_buckets.Length;
1480 Node[] buckets =
new Node[m_serializationCapacity];
1481 int[] countPerLock =
new int[m_serializationConcurrencyLevel];
1482 object[] array =
new object[m_serializationConcurrencyLevel];
1483 for (
int i = 0; i < array.Length; i++)
1485 array[i] =
new object();
1487 m_tables =
new Tables(buckets, array, countPerLock, m_comparer);
1488 InitializeFromCollection(serializationArray);
1489 m_serializationArray =
null;
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
Provides a base class for implementations of the T:System.Collections.Generic.IEqualityComparer`1 gen...
TValue Value
Gets the value in the key/value pair.
static void Write(ref bool location, bool value)
Writes the specified value to the specified field. On systems that require it, inserts a memory barri...
void Reset()
Sets the enumerator to its initial position, which is before the first element in the collection.
bool MoveNext()
Advances the enumerator to the next element of the collection.
Provides the base class for a generic read-only collection.
bool TryAdd(TKey key, TValue value)
Attempts to add the specified key and value to the T:System.Collections.Concurrent....
Represents a thread-safe collection of key/value pairs that can be accessed by multiple threads concu...
ConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer< TKey > comparer)
Initializes a new instance of the T:System.Collections.Concurrent.ConcurrentDictionary`2 class that i...
ICollection< TKey > Keys
Gets an T:System.Collections.Generic.ICollection`1 containing the keys of the T:System....
new IEnumerator< T > GetEnumerator()
Returns an enumerator that iterates through the collection.
The exception that is thrown when the value of an argument is outside the allowable range of values a...
Provides a mechanism that synchronizes access to objects.
bool TryRemove(TKey key, out TValue value)
Attempts to remove and return the value that has the specified key from the T:System....
bool Remove(T item)
Removes the first occurrence of a specific object from the T:System.Collections.Generic....
Exposes the enumerator, which supports a simple iteration over a collection of a specified type....
Represents a strongly-typed, read-only collection of elements.
ConcurrentDictionary()
Initializes a new instance of the T:System.Collections.Concurrent.ConcurrentDictionary`2 class that i...
void CopyTo(T[] array, int arrayIndex)
Copies the elements of the T:System.Collections.Generic.ICollection`1 to an T:System....
Describes the source and destination of a given serialized stream, and provides an additional caller-...
bool TryGetValue(TKey key, out TValue value)
Attempts to get the value associated with the specified key from the T:System.Collections....
ICollection< TValue > Values
Gets an T:System.Collections.Generic.ICollection`1 containing the values in the T:System....
TValue AddOrUpdate(TKey key, TValue addValue, Func< TKey, TValue, TValue > updateValueFactory)
Adds a key/value pair to the T:System.Collections.Concurrent.ConcurrentDictionary`2 if the key does n...
static EqualityComparer< T > Default
Returns a default equality comparer for the type specified by the generic argument.
Supports a simple iteration over a generic collection.
IEnumerable< TValue > Values
Gets an enumerable collection that contains the values in the read-only dictionary.
The exception that is thrown when the key specified for accessing an element in a collection does not...
Defines a key/value pair that can be set or retrieved.
Exposes an enumerator, which supports a simple iteration over a non-generic collection....
SecurityAction
Specifies the security actions that can be performed using declarative security.
static void Enter(object obj)
Acquires an exclusive lock on the specified object.
TKey Key
Gets the key in the key/value pair.
new bool Equals(object x, object y)
Determines whether the specified objects are equal.
TValue GetOrAdd(TKey key, TValue value)
Adds a key/value pair to the T:System.Collections.Concurrent.ConcurrentDictionary`2 if the key does n...
ICollection< TKey > Keys
Gets a collection containing the keys in the T:System.Collections.Generic.Dictionary`2.
Represents a generic collection of key/value pairs.
ConcurrentDictionary(IEqualityComparer< TKey > comparer)
Initializes a new instance of the T:System.Collections.Concurrent.ConcurrentDictionary`2 class that i...
TValue GetOrAdd(TKey key, Func< TKey, TValue > valueFactory)
Adds a key/value pair to the T:System.Collections.Concurrent.ConcurrentDictionary`2 by using the spec...
bool Contains(T item)
Determines whether the T:System.Collections.Generic.ICollection`1 contains a specific value.
int Count
Gets the number of key/value pairs contained in the T:System.Collections.Concurrent....
void Add(object key, object value)
Adds an element with the provided key and value to the T:System.Collections.IDictionary object.
ICollection< TValue > Values
Gets a collection that contains the values in the T:System.Collections.Generic.Dictionary`2.
static sbyte Max(sbyte val1, sbyte val2)
Returns the larger of two 8-bit signed integers.
bool IsReadOnly
Gets a value indicating whether the T:System.Collections.Generic.ICollection`1 is read-only.
bool Remove(TKey key)
Removes the element with the specified key from the T:System.Collections.Generic.IDictionary`2.
bool ContainsKey(TKey key)
Determines whether the T:System.Collections.Concurrent.ConcurrentDictionary`2 contains the specified ...
ConcurrentDictionary(int concurrencyLevel, int capacity)
Initializes a new instance of the T:System.Collections.Concurrent.ConcurrentDictionary`2 class that i...
object Current
Gets the element in the collection at the current position of the enumerator.
static void Exit(object obj)
Releases an exclusive lock on the specified object.
Contains methods for performing volatile memory operations.
int GetHashCode(T obj)
Returns a hash code for the specified object.
IEnumerator< KeyValuePair< TKey, TValue > > GetEnumerator()
Returns an enumerator that iterates through the T:System.Collections.Concurrent.ConcurrentDictionary`...
Represents a generic read-only collection of key/value pairs.
static bool Read(ref bool location)
Reads the value of the specified field. On systems that require it, inserts a memory barrier that pre...
TValue AddOrUpdate(TKey key, Func< TKey, TValue > addValueFactory, Func< TKey, TValue, TValue > updateValueFactory)
Uses the specified functions to add a key/value pair to the T:System.Collections.Concurrent....
int GetHashCode(object obj)
Returns a hash code for the specified object.
The exception that is thrown when one of the arguments provided to a method is not valid.
KeyValuePair< TKey, TValue > [] ToArray()
Copies the key and value pairs stored in the T:System.Collections.Concurrent.ConcurrentDictionary`2 t...
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search...
ConcurrentDictionary(IEnumerable< KeyValuePair< TKey, TValue >> collection, IEqualityComparer< TKey > comparer)
Initializes a new instance of the T:System.Collections.Concurrent.ConcurrentDictionary`2 class that c...
Specifies that the class can be serialized.
void Add(TKey key, TValue value)
Adds an element with the provided key and value to the T:System.Collections.Generic....
Enumerates the elements of a nongeneric dictionary.
This value supports the .NET Framework infrastructure and is not intended to be used directly from yo...
Provides constants and static methods for trigonometric, logarithmic, and other common mathematical f...
Defines size, enumerators, and synchronization methods for all nongeneric collections.
A conditional operation, such as a > b ? a : b in C# or If(a > b, a, b) in Visual Basic.
void CopyTo(Array array, int index)
Copies the elements of the T:System.Collections.ICollection to an T:System.Array, starting at a parti...
Defines a dictionary key/value pair that can be set or retrieved.
void Clear()
Removes all keys and values from the T:System.Collections.Concurrent.ConcurrentDictionary`2.
Represents a nongeneric collection of key/value pairs.
bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue)
Compares the existing value for the specified key with a specified value, and if they are equal,...
IEnumerable< TKey > Keys
Gets an enumerable collection that contains the keys in the read-only dictionary.
The default setting for this enumeration, which is currently F:System.GCCollectionMode....
Supports a simple iteration over a non-generic collection.
void Add(T item)
Adds an item to the T:System.Collections.Generic.ICollection`1.
ConcurrentDictionary(int concurrencyLevel, IEnumerable< KeyValuePair< TKey, TValue >> collection, IEqualityComparer< TKey > comparer)
Initializes a new instance of the T:System.Collections.Concurrent.ConcurrentDictionary`2 class that c...
ConcurrentDictionary(IEnumerable< KeyValuePair< TKey, TValue >> collection)
Initializes a new instance of the T:System.Collections.Concurrent.ConcurrentDictionary`2 class that c...
bool IsEmpty
Gets a value that indicates whether the T:System.Collections.Concurrent.ConcurrentDictionary`2 is emp...