KGy SOFT

ThreadSafeDictionaryTKey, TValue Class

KGy SOFT Core Libraries Help
Implements a thread-safe dictionary, which can be a good alternative for ConcurrentDictionaryTKey, TValue where it is not available (.NET Framework 3.5), or where ConcurrentDictionaryTKey, TValue has a poorer performance.
See the Remarks section for details and for a comparison between ThreadSafeDictionaryTKey, TValue and ConcurrentDictionaryTKey, TValue.
Inheritance Hierarchy

SystemObject
  KGySoft.CollectionsThreadSafeDictionaryTKey, TValue

Namespace:  KGySoft.Collections
Assembly:  KGySoft.CoreLibraries (in KGySoft.CoreLibraries.dll) Version: 6.0.0-rc.1
Syntax

[SerializableAttribute]
public class ThreadSafeDictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
	ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, 
	IEnumerable, IDictionary, ICollection, ISerializable, IDeserializationCallback

Type Parameters

TKey
Type of the keys stored in the dictionary.
TValue
Type of the values stored in the dictionary.

The ThreadSafeDictionaryTKey, TValue type exposes the following members.

Constructors

  NameDescription
Public methodThreadSafeDictionaryTKey, TValue
Initializes a new instance of the ThreadSafeDictionaryTKey, TValue class that is empty and uses the default comparer and Auto hashing strategy.
Public methodThreadSafeDictionaryTKey, TValue(IEqualityComparerTKey, HashingStrategy)
Initializes a new instance of the ThreadSafeDictionaryTKey, TValue class that is empty and uses the specified comparer and hashing strategy.
Public methodThreadSafeDictionaryTKey, TValue(Int32, HashingStrategy)
Initializes a new instance of the ThreadSafeDictionaryTKey, TValue class that is empty and uses the default comparer and the specified hashing strategy.
Protected methodThreadSafeDictionaryTKey, TValue(SerializationInfo, StreamingContext)
Initializes a new instance of the ThreadSafeDictionaryTKey, TValue class from serialized data.
Public methodThreadSafeDictionaryTKey, TValue(IEnumerableKeyValuePairTKey, TValue, IEqualityComparerTKey, HashingStrategy)
Initializes a new instance of the ThreadSafeDictionaryTKey, TValue class from the specified collection and uses the specified comparer and hashing strategy.
Public methodThreadSafeDictionaryTKey, TValue(Int32, IEqualityComparerTKey, HashingStrategy)
Initializes a new instance of the ThreadSafeDictionaryTKey, TValue class that is empty and uses the specified comparer and hashing strategy.
Top
Properties

  NameDescription
Public propertyCount
Gets the number of elements contained in this ThreadSafeDictionaryTKey, TValue.
Public propertyIsEmpty
Gets whether this ThreadSafeDictionaryTKey, TValue is empty.
Public propertyItem
Gets or sets the value associated with the specified key.
Public propertyKeys
Gets a collection reflecting the keys stored in this ThreadSafeDictionaryTKey, TValue.
Public propertyMergeInterval
Gets or sets the minimum lifetime for the temporarily created internal locking storage when adding new keys to the ThreadSafeDictionaryTKey, TValue.
Default value: 100 milliseconds.
See the Remarks section for details.
Public propertyPreserveMergedKeys
Gets or sets whether keys of entries that have already been merged into the faster lock-free storage are preserved even when their value is removed.
Default value: .
See the Remarks section for details.
Public propertyValues
Gets a collection reflecting the values stored in this ThreadSafeDictionaryTKey, TValue.
Top
Methods

  NameDescription
Public methodAdd
Adds an element with the provided key and value to the ThreadSafeDictionaryTKey, TValue.
Public methodAddOrUpdate(TKey, FuncTKey, TValue, FuncTKey, TValue, TValue)
Uses the specified delegates to add a key/value pair to the ThreadSafeDictionaryTKey, TValue if the key does not already exist, or to update a key/value pair in the ThreadSafeDictionaryTKey, TValue if the key already exists.
Public methodAddOrUpdate(TKey, TValue, FuncTKey, TValue, TValue)
Adds a key/value pair to the ThreadSafeDictionaryTKey, TValue if the key does not already exist, or updates a key/value pair in the ThreadSafeDictionaryTKey, TValue by using the specified updateValueFactory if the key already exists.
Public methodAddOrUpdate(TKey, TValue, TValue)
Adds or updates a key/value pair in the ThreadSafeDictionaryTKey, TValue based on whether the specified key already exists.
Public methodAddOrUpdateTArg(TKey, FuncTKey, TArg, TValue, FuncTKey, TValue, TArg, TValue, TArg)
Uses the specified delegates to add a key/value pair to the ThreadSafeDictionaryTKey, TValue if the key does not already exist, or to update a key/value pair in the ThreadSafeDictionaryTKey, TValue if the key already exists.
Public methodClear
Removes all items from the ThreadSafeDictionaryTKey, TValue.
See the Remarks section for details.
Public methodContainsKey
Determines whether the ThreadSafeDictionaryTKey, TValue contains an element with the specified key.
Public methodContainsValue
Determines whether the ThreadSafeDictionaryTKey, TValue contains an element with the specified value.
Public methodEnsureMerged
Ensures that all elements in this ThreadSafeDictionaryTKey, TValue are merged into the faster lock-free storage.
See the Remarks section of the MergeInterval property for details.
Public methodGetEnumerator
Returns an enumerator that iterates through the keys and values of this ThreadSafeDictionaryTKey, TValue.
Protected methodGetObjectData
In a derived class populates a SerializationInfo with the additional data of the derived type needed to serialize the target object.
Public methodGetOrAdd(TKey, FuncTKey, TValue)
Adds a key/value pair to the ThreadSafeDictionaryTKey, TValue by using the specified addValueFactory if the key does not already exist, and returns either the added or the existing value.
Public methodGetOrAdd(TKey, TValue)
Adds a key/value pair to the ThreadSafeDictionaryTKey, TValue if the key does not already exist, and returns either the added or the existing value.
Public methodGetOrAddTArg(TKey, FuncTKey, TArg, TValue, TArg)
Adds a key/value pair to the ThreadSafeDictionaryTKey, TValue by using the specified addValueFactory if the key does not already exist, and returns either the added or the existing value.
Protected methodOnDeserialization
In a derived class restores the state the deserialized instance.
Public methodReset
Removes all keys and values from the ThreadSafeDictionaryTKey, TValue.
See the Remarks section of the Clear method for details.
Public methodToArray
Copies the key and value pairs stored in the ThreadSafeDictionaryTKey, TValue to a new array.
Public methodTrimExcess
Forces to perform a merge while removing all possibly allocated but already deleted entries from the lock-free storage, even if the PreserveMergedKeys property is .
See the Remarks section of the PreserveMergedKeys property for details.
Public methodTryAdd
Tries to add the specified key and value to the ThreadSafeDictionaryTKey, TValue.
Public methodTryGetValue
Tries to get the value associated with the specified key from the ThreadSafeDictionaryTKey, TValue.
Public methodTryRemove(TKey)
Tries to remove the value with the specified key from the ThreadSafeDictionaryTKey, TValue.
Public methodTryRemove(TKey, TValue)
Tries to remove the item from the ThreadSafeDictionaryTKey, TValue that has the specified key and value.
Public methodTryRemove(TKey, TValue)
Tries to remove and return the value with the specified key from the ThreadSafeDictionaryTKey, TValue.
Public methodTryUpdate
Updates the value associated with key to newValue if the existing value with key is equal to originalValue.
Top
Extension Methods

  NameDescription
Public Extension MethodAddRangeKeyValuePairTKey, TValue (Defined by CollectionExtensions.)
Public Extension MethodAsThreadSafeKeyValuePairTKey, TValue (Defined by CollectionExtensions.)
Public Extension MethodConvert(Type, CultureInfo)Overloaded.
Converts an Object specified in the obj parameter to the desired targetType.
See the Examples section of the generic ConvertTTarget(Object, CultureInfo) overload for an example.
(Defined by ObjectExtensions.)
Public Extension MethodCode exampleConvertTTarget(CultureInfo)Overloaded.
Converts an Object specified in the obj parameter to the desired TTarget.
(Defined by ObjectExtensions.)
Public Extension MethodForEachKeyValuePairTKey, TValue
Similarly to the List<T>.ForEach method, processes an action on each element of an enumerable collection.
(Defined by EnumerableExtensions.)
Public Extension MethodGetRandomElementKeyValuePairTKey, TValue(Boolean)Overloaded.
Gets a random element from the enumerable source using a new FastRandom instance.
(Defined by EnumerableExtensions.)
Public Extension MethodGetRandomElementKeyValuePairTKey, TValue(Random, Boolean)Overloaded.
Gets a random element from the enumerable source using a specified Random instance.
(Defined by EnumerableExtensions.)
Public Extension MethodIn (Defined by ObjectExtensions.)
Public Extension MethodIndexOf(FuncObject, Boolean)Overloaded.
Searches for an element in the source enumeration where the specified predicate returns .
(Defined by EnumerableExtensions.)
Public Extension MethodIndexOf(Object)Overloaded.
Searches for an element in the source enumeration.
(Defined by EnumerableExtensions.)
Public Extension MethodIndexOfKeyValuePairTKey, TValue(FuncKeyValuePairTKey, TValue, Boolean)Overloaded.
Searches for an element in the source enumeration where the specified predicate returns .
(Defined by EnumerableExtensions.)
Public Extension MethodIndexOfKeyValuePairTKey, TValue(KeyValuePairTKey, TValue)Overloaded.
Searches for an element in the source enumeration.
(Defined by EnumerableExtensions.)
Public Extension MethodIsNullOrEmptyOverloaded.
Determines whether the specified source is  or empty (has no elements).
(Defined by EnumerableExtensions.)
Public Extension MethodIsNullOrEmptyKeyValuePairTKey, TValueOverloaded.
Determines whether the specified source is  or empty (has no elements).
(Defined by EnumerableExtensions.)
Public Extension MethodJoinKeyValuePairTKey, TValue(String)Overloaded.
Concatenates the items of the source collection into a new string instance using the specified separator between the items.
(Defined by EnumerableExtensions.)
Public Extension MethodJoinKeyValuePairTKey, TValue(Char)Overloaded.
Concatenates the items of the source collection into a new string instance using the specified separator between the items.
(Defined by EnumerableExtensions.)
Public Extension MethodShuffleKeyValuePairTKey, TValueOverloaded.
Shuffles an enumerable source (randomizes its elements) using a new FastRandom instance.
(Defined by EnumerableExtensions.)
Public Extension MethodShuffleKeyValuePairTKey, TValue(Int32)Overloaded.
Shuffles an enumerable source (randomizes its elements) using the provided seed with a new FastRandom instance.
(Defined by EnumerableExtensions.)
Public Extension MethodShuffleKeyValuePairTKey, TValue(Guid)Overloaded.
Shuffles an enumerable source (randomizes its elements) using the provided seed with a new FastRandom instance.
(Defined by EnumerableExtensions.)
Public Extension MethodShuffleKeyValuePairTKey, TValue(Random)Overloaded.
Shuffles an enumerable source (randomizes its elements) using a specified Random instance.
(Defined by EnumerableExtensions.)
Public Extension MethodToCircularListKeyValuePairTKey, TValue (Defined by EnumerableExtensions.)
Public Extension MethodToStringKeyedDictionaryKeyValuePairTKey, TValue(FuncKeyValuePairTKey, TValue, String, StringSegmentComparer)Overloaded. (Defined by EnumerableExtensions.)
Public Extension MethodToStringKeyedDictionaryKeyValuePairTKey, TValue, TValue(FuncKeyValuePairTKey, TValue, String, FuncKeyValuePairTKey, TValue, TValue, StringSegmentComparer)Overloaded. (Defined by EnumerableExtensions.)
Public Extension MethodTryAdd(Object, Boolean, Boolean)Overloaded.
Tries to add the specified item to the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryAddKeyValuePairTKey, TValue(KeyValuePairTKey, TValue, Boolean, Boolean)Overloaded.
Tries to add the specified item to the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryAddRange(IEnumerable, Boolean, Boolean)Overloaded.
Tries to add the specified collection to the target collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryAddRangeKeyValuePairTKey, TValue(IEnumerableKeyValuePairTKey, TValue, Boolean, Boolean)Overloaded.
Tries to add the specified collection to the target collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryClear(Boolean, Boolean)Overloaded.
Tries to remove all elements from the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryClearKeyValuePairTKey, TValue(Boolean, Boolean)Overloaded.
Tries to remove all elements from the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryConvert(Type, Object)Overloaded.
Tries to convert an Object specified in the obj parameter to the desired targetType.
(Defined by ObjectExtensions.)
Public Extension MethodTryConvert(Type, CultureInfo, Object)Overloaded.
Tries to convert an Object specified in the obj parameter to the desired targetType.
(Defined by ObjectExtensions.)
Public Extension MethodTryConvertTTarget(TTarget)Overloaded.
Tries to convert an Object specified in the obj parameter to the desired TTarget.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example.
(Defined by ObjectExtensions.)
Public Extension MethodTryConvertTTarget(CultureInfo, TTarget)Overloaded.
Tries to convert an Object specified in the obj parameter to the desired TTarget.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example.
(Defined by ObjectExtensions.)
Public Extension MethodTryGetElementAt(Int32, Object, Boolean, Boolean)Overloaded.
Tries to get an item at the specified index in the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryGetElementAtKeyValuePairTKey, TValue(Int32, KeyValuePairTKey, TValue, Boolean, Boolean)Overloaded.
Tries to get an item at the specified index in the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryInsert(Int32, Object, Boolean, Boolean)Overloaded.
Tries to insert the specified item at the specified index to the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryInsertKeyValuePairTKey, TValue(Int32, KeyValuePairTKey, TValue, Boolean, Boolean)Overloaded.
Tries to insert the specified item at the specified index to the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryInsertRange(Int32, IEnumerable, Boolean, Boolean)Overloaded.
Tries to insert the specified collection into the target collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryInsertRangeKeyValuePairTKey, TValue(Int32, IEnumerableKeyValuePairTKey, TValue, Boolean, Boolean)Overloaded.
Tries to insert the specified collection into the target collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryRemove(Object, Boolean, Boolean)Overloaded.
Tries to remove the specified item from to the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryRemoveKeyValuePairTKey, TValue(KeyValuePairTKey, TValue, Boolean, Boolean)Overloaded.
Tries to remove the specified item from to the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryRemoveAt(Int32, Boolean, Boolean)Overloaded.
Tries to remove an item at the specified index from the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryRemoveAtKeyValuePairTKey, TValue(Int32, Boolean, Boolean)Overloaded.
Tries to remove an item at the specified index from the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTryRemoveRange(Int32, Int32, Boolean, Boolean)Overloaded.
Tries to remove count amount of items from the specified collection at the specified index.
(Defined by EnumerableExtensions.)
Public Extension MethodTryRemoveRangeKeyValuePairTKey, TValue(Int32, Int32, Boolean, Boolean)Overloaded.
Tries to remove count amount of items from the specified collection at the specified index.
(Defined by EnumerableExtensions.)
Public Extension MethodTryReplaceRange(Int32, Int32, IEnumerable, Boolean, Boolean)Overloaded.
Tries to remove count amount of items from the target at the specified index, and to insert the specified collection at the same position. The number of elements in collection can be different from the amount of removed items.
(Defined by EnumerableExtensions.)
Public Extension MethodTryReplaceRangeKeyValuePairTKey, TValue(Int32, Int32, IEnumerableKeyValuePairTKey, TValue, Boolean, Boolean)Overloaded.
Tries to remove count amount of items from the target at the specified index, and to insert the specified collection at the same position. The number of elements in collection can be different from the amount of removed items.
(Defined by EnumerableExtensions.)
Public Extension MethodTrySetElementAt(Int32, Object, Boolean, Boolean)Overloaded.
Tries to set the specified item at the specified index in the collection.
(Defined by EnumerableExtensions.)
Public Extension MethodTrySetElementAtKeyValuePairTKey, TValue(Int32, KeyValuePairTKey, TValue, Boolean, Boolean)Overloaded.
Tries to set the specified item at the specified index in the collection.
(Defined by EnumerableExtensions.)
Top
Remarks

The purpose of ThreadSafeDictionaryTKey, TValue is similar to ConcurrentDictionaryTKey, TValue but its approach is somewhat different. While ConcurrentDictionaryTKey, TValue uses a group of locks to perform modifications (their amount can be configured or depends on the number of CPU cores); on the other hand, ThreadSafeDictionaryTKey, TValue uses two separate internal storage: items with new keys are added to a temporary storage using a single lock, which might regularly be merged into a faster lock-free storage, depending on the value of the MergeInterval property. Once the items are merged, their access (both read and write) becomes lock free. Even deleting and re-adding a value for the same key becomes faster after the key is merged into the lock-free storage.

Note Note
Therefore, ThreadSafeDictionaryTKey, TValue is not always a good alternative of ConcurrentDictionaryTKey, TValue. If new keys are continuously added, then always a shared lock is used, in which case ConcurrentDictionaryTKey, TValue might perform better, unless you need to use some members, which are very slow in ConcurrentDictionaryTKey, TValue (see the table below). If the newly added elements are regularly removed, make sure the PreserveMergedKeys property is ; otherwise, the already merged keys are not removed from the ThreadSafeDictionaryTKey, TValue even if they are deleted or when you call the Clear method. To remove even the merged keys you must call the Reset method, or to remove the deleted keys only you can explicitly call the TrimExcess method.

Comparison with ConcurrentDictionaryTKey, TValue

When to use ThreadSafeDictionaryTKey, TValue:

Performance comparison with ConcurrentDictionaryTKey, TValue (default concurrency level depends on ProcessorCount):

Member(s) or operationThreadSafeDictionaryTKey, TValueConcurrentDictionaryTKey, TValue, concurrency level = 2ConcurrentDictionaryTKey, TValue, concurrency level = 8
CountFastest5.01x slower530.44x slower
TryAdd (10 million new keys, sequential)1.07x slowerFastest1.25x slower
TryAdd (10 million new keys, parallel)1.02x slowerFastest1.53x slower
TryGetValue (no collisions, TKey is int)1.55x slowerFastestFastest
TryGetValue (no collisions, TKey is string)Fastest1.26x slower1.26x slower
TryGetValue (many key collisions)Fastest1.92x slower2.01x slower
Indexer set (sequential, TKey is int)Fastest1.07x slower1.07x slower
Indexer set (parallel, TKey is int)Fastest2.03x slower1.01x slower
TryUpdate (sequential)Fastest1.21x slower1.17x slower
TryUpdate (parallel)Fastest4.02x slower1.27x slower
TryRemove + TryAdd (same key, sequential)Fastest1.12x slower1.16x slower
TryRemove + TryAdd (same key, parallel)Fastest2.53x slower2.43x slower
Enumerating itemsFastest2.87x slower262.45x slower
Enumerating KeysFastest117.92x slower368.11x slower
ToArray1.69x slowerFastest2.12x slower
AddOrUpdate (random existing keys, sequential)Fastest3.35x slower3.16x slower
AddOrUpdate (random existing keys, parallel)Fastest9.74x slower2.27x slower
GetOrAdd (random existing keys)1.11x slowerFastestFastest
Tip Tip
If TKey is string and it is safe to use a non-randomized string comparer, then you can pass StringSegmentComparer.Ordinal to the constructor for even better performance. Or, you can use StringSegmentComparer.OrdinalRandomized to use a comparer with randomized hash also on platforms where default string hashing is not randomized (eg. .NET Framework 3.5).

Incompatibilities with ConcurrentDictionaryTKey, TValue:

See Also

Reference