See the Remarks section for details and for a comparison between ThreadSafeDictionaryTKey, TValue and ConcurrentDictionaryTKey, TValue.
KGySoft.CollectionsThreadSafeDictionaryTKey, TValue
Namespace: KGySoft.Collections
Assembly: KGySoft.CoreLibraries (in KGySoft.CoreLibraries.dll) Version: 7.0.0-preview.3
[SerializableAttribute] public class ThreadSafeDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IDictionary, ICollection, ISerializable, IDeserializationCallback, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>
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.
Name | Description | |
---|---|---|
![]() | ThreadSafeDictionaryTKey, TValue |
Initializes a new instance of the ThreadSafeDictionaryTKey, TValue class that is empty
and uses the default comparer and Auto hashing strategy.
|
![]() | ThreadSafeDictionaryTKey, TValue(IEqualityComparerTKey, HashingStrategy) |
Initializes a new instance of the ThreadSafeDictionaryTKey, TValue class that is empty
and uses the specified comparer and hashing strategy.
|
![]() | ThreadSafeDictionaryTKey, 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.
|
![]() | ThreadSafeDictionaryTKey, TValue(SerializationInfo, StreamingContext) |
Initializes a new instance of the ThreadSafeDictionaryTKey, TValue class from serialized data.
|
![]() | ThreadSafeDictionaryTKey, 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.
|
![]() | ThreadSafeDictionaryTKey, TValue(Int32, IEqualityComparerTKey, HashingStrategy) |
Initializes a new instance of the ThreadSafeDictionaryTKey, TValue class that is empty
and uses the specified comparer and hashing strategy.
|
Name | Description | |
---|---|---|
![]() | Comparer |
Gets the IEqualityComparerT that is used to determine equality of keys for this ThreadSafeDictionaryTKey, TValue.
|
![]() | Count |
Gets the number of elements contained in this ThreadSafeDictionaryTKey, TValue.
|
![]() | IsEmpty |
Gets whether this ThreadSafeDictionaryTKey, TValue is empty.
|
![]() | Item |
Gets or sets the value associated with the specified key.
|
![]() | Keys |
Gets a collection reflecting the keys stored in this ThreadSafeDictionaryTKey, TValue.
|
![]() | MergeInterval |
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. |
![]() | PreserveMergedKeys |
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. |
![]() | Values |
Gets a collection reflecting the values stored in this ThreadSafeDictionaryTKey, TValue.
|
Name | Description | |
---|---|---|
![]() | Add |
Adds an element with the provided key and value to the ThreadSafeDictionaryTKey, TValue.
|
![]() | AddOrUpdate(TKey, TValue, TValue) |
Adds or updates a key/value pair in the ThreadSafeDictionaryTKey, TValue based on whether the specified key already exists.
|
![]() | AddOrUpdate(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.
|
![]() | AddOrUpdate(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.
|
![]() | AddOrUpdateTArg(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.
|
![]() | Clear |
Removes all items from the ThreadSafeDictionaryTKey, TValue.
See the Remarks section for details. |
![]() | ContainsKey |
Determines whether the ThreadSafeDictionaryTKey, TValue contains an element with the specified key.
|
![]() | ContainsValue |
Determines whether the ThreadSafeDictionaryTKey, TValue contains an element with the specified value.
|
![]() | EnsureMerged |
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. |
![]() | GetEnumerator |
Returns an enumerator that iterates through the keys and values of this ThreadSafeDictionaryTKey, TValue.
See the Remarks section for details. |
![]() | GetObjectData |
In a derived class populates a SerializationInfo with the additional data of the derived type needed to serialize the target object.
|
![]() | GetOrAdd(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.
|
![]() | GetOrAdd(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.
|
![]() | GetOrAddTArg(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.
|
![]() | OnDeserialization |
In a derived class restores the state the deserialized instance.
|
![]() | Remove |
Tries to remove the value with the specified key from the ThreadSafeDictionaryTKey, TValue.
This method just calls the TryRemove method. It exists just for providing compatibility with the DictionaryTKey, TValue type.
|
![]() | Reset |
Removes all keys and values from the ThreadSafeDictionaryTKey, TValue.
See the Remarks section of the Clear method for details. |
![]() | ToArray |
Copies the key and value pairs stored in the ThreadSafeDictionaryTKey, TValue to a new array.
|
![]() | TrimExcess |
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. |
![]() | TryAdd |
Tries to add the specified key and value to the ThreadSafeDictionaryTKey, TValue.
|
![]() | TryGetValue |
Tries to get the value associated with the specified key from the ThreadSafeDictionaryTKey, TValue.
|
![]() | TryRemove(TKey) |
Tries to remove the value with the specified key from the ThreadSafeDictionaryTKey, TValue.
|
![]() | TryRemove(TKey, TValue) |
Tries to remove the item from the ThreadSafeDictionaryTKey, TValue that has the specified key and value.
|
![]() | TryRemove(TKey, TValue) |
Tries to remove and return the value with the specified key from the ThreadSafeDictionaryTKey, TValue.
|
![]() | TryUpdate |
Updates the value associated with key to newValue
if the existing value with key is equal to originalValue.
|
Name | Description | |
---|---|---|
![]() | AddRangeKeyValuePairTKey, TValue | (Defined by CollectionExtensions.) |
![]() | AsThreadSafeKeyValuePairTKey, TValue |
Returns a LockingCollectionT, which provides a thread-safe wrapper for the specified collection.
This only means that if the members are accessed through the returned LockingCollectionT, then the inner state of the wrapped collection remains always consistent and not that all of the multi-threading concerns can be ignored.
(Defined by CollectionExtensions.)See the Remarks section of the LockingCollectionT class for details and some examples. |
![]() | Convert(Type, CultureInfo) | Overloaded.
Converts an Object specified in the obj parameter to the desired targetType.
(Defined by ObjectExtensions.)See the Examples section of the generic ConvertTTarget(Object, CultureInfo) overload for an example. |
![]() ![]() | ConvertTTarget(CultureInfo) | Overloaded.
Converts an Object specified in the obj parameter to the desired TTarget.
(Defined by ObjectExtensions.)See the Remarks section for details. |
![]() | ForEachKeyValuePairTKey, TValue |
Similarly to the List<T>.ForEach method, processes an action on each element of an enumerable collection.
(Defined by EnumerableExtensions.) |
![]() | GetRandomElementKeyValuePairTKey, TValue(Boolean) | Overloaded.
Gets a random element from the enumerable source using a new FastRandom instance.
(Defined by EnumerableExtensions.) |
![]() | GetRandomElementKeyValuePairTKey, TValue(Random, Boolean) | Overloaded.
Gets a random element from the enumerable source using a specified Random instance.
(Defined by EnumerableExtensions.) |
![]() | In |
Gets whether item is among the elements of set.
(Defined by ObjectExtensions.)See the Examples section of the generic InT(T, T) overload for an example. |
![]() | IndexOf(FuncObject, Boolean) | Overloaded.
Searches for an element in the source enumeration where the specified predicate returns .
(Defined by EnumerableExtensions.) |
![]() | IndexOf(Object) | Overloaded.
Searches for an element in the source enumeration.
(Defined by EnumerableExtensions.) |
![]() | IndexOfKeyValuePairTKey, TValue(FuncKeyValuePairTKey, TValue, Boolean) | Overloaded.
Searches for an element in the source enumeration where the specified predicate returns .
(Defined by EnumerableExtensions.) |
![]() | IndexOfKeyValuePairTKey, TValue(KeyValuePairTKey, TValue) | Overloaded.
Searches for an element in the source enumeration.
(Defined by EnumerableExtensions.) |
![]() | IsNullOrEmpty | Overloaded.
Determines whether the specified source is or empty (has no elements).
(Defined by EnumerableExtensions.) |
![]() | IsNullOrEmptyKeyValuePairTKey, TValue | Overloaded.
Determines whether the specified source is or empty (has no elements).
(Defined by EnumerableExtensions.) |
![]() | JoinKeyValuePairTKey, 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.) |
![]() | JoinKeyValuePairTKey, 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.) |
![]() | ShuffleKeyValuePairTKey, TValue | Overloaded.
Shuffles an enumerable source (randomizes its elements) using a new FastRandom instance.
(Defined by EnumerableExtensions.) |
![]() | ShuffleKeyValuePairTKey, TValue(Guid) | Overloaded.
Shuffles an enumerable source (randomizes its elements) using the provided seed with a new FastRandom instance.
(Defined by EnumerableExtensions.) |
![]() | ShuffleKeyValuePairTKey, TValue(Int32) | Overloaded.
Shuffles an enumerable source (randomizes its elements) using the provided seed with a new FastRandom instance.
(Defined by EnumerableExtensions.) |
![]() | ShuffleKeyValuePairTKey, TValue(Random) | Overloaded.
Shuffles an enumerable source (randomizes its elements) using a specified Random instance.
(Defined by EnumerableExtensions.) |
![]() | ToCircularListKeyValuePairTKey, TValue |
Creates a CircularListT from an IEnumerableT.
(Defined by EnumerableExtensions.) |
![]() | ToStringKeyedDictionaryKeyValuePairTKey, TValue(FuncKeyValuePairTKey, TValue, String, StringSegmentComparer) | Overloaded.
Creates a StringKeyedDictionaryTValue from an IEnumerableT instance using the specified keySelector delegate and a comparer.
(Defined by EnumerableExtensions.) |
![]() | ToStringKeyedDictionaryKeyValuePairTKey, TValue, TValue(FuncKeyValuePairTKey, TValue, String, FuncKeyValuePairTKey, TValue, TValue, StringSegmentComparer) | Overloaded.
Creates a StringKeyedDictionaryTValue from an IEnumerableT instance using the specified key and value selector delegates and a comparer.
(Defined by EnumerableExtensions.) |
![]() | TryAdd(Object, Boolean, Boolean) | Overloaded.
Tries to add the specified item to the collection.
(Defined by EnumerableExtensions.) |
![]() | TryAddKeyValuePairTKey, TValue(KeyValuePairTKey, TValue, Boolean, Boolean) | Overloaded.
Tries to add the specified item to the collection.
(Defined by EnumerableExtensions.) |
![]() | TryAddRange(IEnumerable, Boolean, Boolean) | Overloaded.
Tries to add the specified collection to the target collection.
(Defined by EnumerableExtensions.) |
![]() | TryAddRangeKeyValuePairTKey, TValue(IEnumerableKeyValuePairTKey, TValue, Boolean, Boolean) | Overloaded.
Tries to add the specified collection to the target collection.
(Defined by EnumerableExtensions.) |
![]() | TryClear(Boolean, Boolean) | Overloaded.
Tries to remove all elements from the collection.
(Defined by EnumerableExtensions.) |
![]() | TryClearKeyValuePairTKey, TValue(Boolean, Boolean) | Overloaded.
Tries to remove all elements from the collection.
(Defined by EnumerableExtensions.) |
![]() | TryConvert(Type, Object) | Overloaded.
Tries to convert an Object specified in the obj parameter to the desired targetType.
(Defined by ObjectExtensions.)See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. |
![]() | TryConvert(Type, CultureInfo, Object) | Overloaded.
Tries to convert an Object specified in the obj parameter to the desired targetType.
(Defined by ObjectExtensions.)See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. |
![]() | TryConvertTTarget(TTarget) | Overloaded.
Tries to convert an Object specified in the obj parameter to the desired TTarget.
(Defined by ObjectExtensions.)See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. |
![]() | TryConvertTTarget(CultureInfo, TTarget) | Overloaded.
Tries to convert an Object specified in the obj parameter to the desired TTarget.
(Defined by ObjectExtensions.)See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. |
![]() | TryGetCount(Int32) | Overloaded.
Tries to get the number of elements in the source enumeration without enumerating it.
(Defined by EnumerableExtensions.) |
![]() | TryGetCountKeyValuePairTKey, TValue(Int32) | Overloaded.
Tries to get the number of elements in the source enumeration without enumerating it.
(Defined by EnumerableExtensions.) |
![]() | TryGetElementAt(Int32, Object, Boolean, Boolean) | Overloaded.
Tries to get an item at the specified index in the collection.
(Defined by EnumerableExtensions.) |
![]() | TryGetElementAtKeyValuePairTKey, TValue(Int32, KeyValuePairTKey, TValue, Boolean, Boolean) | Overloaded.
Tries to get an item at the specified index in the collection.
(Defined by EnumerableExtensions.) |
![]() | TryInsert(Int32, Object, Boolean, Boolean) | Overloaded.
Tries to insert the specified item at the specified index to the collection.
(Defined by EnumerableExtensions.) |
![]() | TryInsertKeyValuePairTKey, TValue(Int32, KeyValuePairTKey, TValue, Boolean, Boolean) | Overloaded.
Tries to insert the specified item at the specified index to the collection.
(Defined by EnumerableExtensions.) |
![]() | TryInsertRange(Int32, IEnumerable, Boolean, Boolean) | Overloaded.
Tries to insert the specified collection into the target collection.
(Defined by EnumerableExtensions.) |
![]() | TryInsertRangeKeyValuePairTKey, TValue(Int32, IEnumerableKeyValuePairTKey, TValue, Boolean, Boolean) | Overloaded.
Tries to insert the specified collection into the target collection.
(Defined by EnumerableExtensions.) |
![]() | TryRemove(Object, Boolean, Boolean) | Overloaded.
Tries to remove the specified item from to the collection.
(Defined by EnumerableExtensions.) |
![]() | TryRemoveKeyValuePairTKey, TValue(KeyValuePairTKey, TValue, Boolean, Boolean) | Overloaded.
Tries to remove the specified item from to the collection.
(Defined by EnumerableExtensions.) |
![]() | TryRemoveAt(Int32, Boolean, Boolean) | Overloaded.
Tries to remove an item at the specified index from the collection.
(Defined by EnumerableExtensions.) |
![]() | TryRemoveAtKeyValuePairTKey, TValue(Int32, Boolean, Boolean) | Overloaded.
Tries to remove an item at the specified index from the collection.
(Defined by EnumerableExtensions.) |
![]() | TryRemoveRange(Int32, Int32, Boolean, Boolean) | Overloaded.
Tries to remove count amount of items from the specified collection at the specified index.
(Defined by EnumerableExtensions.) |
![]() | TryRemoveRangeKeyValuePairTKey, TValue(Int32, Int32, Boolean, Boolean) | Overloaded.
Tries to remove count amount of items from the specified collection at the specified index.
(Defined by EnumerableExtensions.) |
![]() | TryReplaceRange(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.) |
![]() | TryReplaceRangeKeyValuePairTKey, 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.) |
![]() | TrySetElementAt(Int32, Object, Boolean, Boolean) | Overloaded.
Tries to set the specified item at the specified index in the collection.
(Defined by EnumerableExtensions.) |
![]() | TrySetElementAtKeyValuePairTKey, TValue(Int32, KeyValuePairTKey, TValue, Boolean, Boolean) | Overloaded.
Tries to set the specified item at the specified index in the collection.
(Defined by EnumerableExtensions.) |
![]() |
---|
|
The purpose of ThreadSafeDictionaryTKey, TValue is similar to ConcurrentDictionaryTKey, TValue but its approach is somewhat different. The 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.
![]() |
---|
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:
- If it is known that a fixed set of keys will be used. ThreadSafeDictionaryTKey, TValue is fast if the already added keys are updated, or even deleted and re-added with any value. In this case consider to set the PreserveMergedKeys to , so it is not checked whether a cleanup should be performed due to many deleted items.
- If you access mainly existing keys by the AddOrUpdate methods, which are separate try get/add/update operations at ConcurrentDictionaryTKey, TValue but are optimized at ThreadSafeDictionaryTKey, TValue to avoid multiple lookups.
- If it is needed to access Count, enumerate the items or Keys/Values, or you need to call ToArray, which are particularly slow in case of ConcurrentDictionaryTKey, TValue.
- If it is expected that there will be many hash collisions.
- If the dictionary is needed to be serialized.
Performance comparison with ConcurrentDictionaryTKey, TValue (default concurrency level depends on ProcessorCount):
Member(s) or operation | ThreadSafeDictionaryTKey, TValue | ConcurrentDictionaryTKey, TValue, concurrency level = 2 | ConcurrentDictionaryTKey, TValue, concurrency level = 8 |
---|---|---|---|
Count | Fastest | 5.01x slower | 530.44x slower |
TryAdd (10 million new keys, sequential) | 1.07x slower | Fastest | 1.25x slower |
TryAdd (10 million new keys, parallel) | 1.02x slower | Fastest | 1.53x slower |
TryGetValue (no collisions, TKey is int) | 1.55x slower | Fastest | Fastest |
TryGetValue (no collisions, TKey is string) | Fastest | 1.26x slower | 1.26x slower |
TryGetValue (many key collisions) | Fastest | 1.92x slower | 2.01x slower |
Indexer set (sequential, TKey is int) | Fastest | 1.07x slower | 1.07x slower |
Indexer set (parallel, TKey is int) | Fastest | 2.03x slower | 1.01x slower |
TryUpdate (sequential) | Fastest | 1.21x slower | 1.17x slower |
TryUpdate (parallel) | Fastest | 4.02x slower | 1.27x slower |
TryRemove + TryAdd (same key, sequential) | Fastest | 1.12x slower | 1.16x slower |
TryRemove + TryAdd (same key, parallel) | Fastest | 2.53x slower | 2.43x slower |
Enumerating items | Fastest | 2.87x slower | 262.45x slower |
Enumerating Keys | Fastest | 117.92x slower | 368.11x slower |
ToArray | 1.69x slower | Fastest | 2.12x slower |
AddOrUpdate (random existing keys, sequential) | Fastest | 3.35x slower | 3.16x slower |
AddOrUpdate (random existing keys, parallel) | Fastest | 9.74x slower | 2.27x slower |
GetOrAdd (random existing keys) | 1.11x slower | Fastest | Fastest |
![]() |
---|
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:
- Constructor signatures are different
- The Keys and Values property of ThreadSafeDictionaryTKey, TValue return wrappers for the current keys and values (enumerating the same instance again and again may yield different items), whereas ConcurrentDictionaryTKey, TValue return a snapshot for these properties.
- The SyncRoot property of Keys and Values throw a NotSupportedException just like for their owner ThreadSafeDictionaryTKey, TValue instance. In contrast, in case of ConcurrentDictionaryTKey, TValue only the dictionary itself throws an exception when accessing the SyncRoot, whereas its keys and values don't.
Incompatibilities with DictionaryTKey, TValue:
- Constructor signatures are different, though due to default parameters they are compile-compatible.
- The ThreadSafeDictionaryTKey, TValue does not have an EnsureCapacity method.
- The GetObjectData and OnDeserialization methods are protected rather than public.
- The enumerators of the Keys and Values properties do not support the IEnumerator.Reset method.
- The SyncRoot property of Keys and Values as well as for the ThreadSafeDictionaryTKey, TValue itself throw a NotSupportedException.