From af6efef8d042259faade28df0b2eb532ba064807 Mon Sep 17 00:00:00 2001 From: Shawn LaMountain Date: Sat, 19 Feb 2022 18:26:19 -0500 Subject: [PATCH] Added DictionaryThreadSafe object --- .../Collections/DictionaryThreadSafe.cs | 242 ++++++++++++++++++ .../ObservableDictionaryThreadSafe.cs | 214 +--------------- .../Interfaces/IDictionaryThreadSafe.cs | 15 ++ .../IObservableDictionaryThreadSafe.cs | 4 +- 4 files changed, 273 insertions(+), 202 deletions(-) create mode 100644 src/ThunderDesign.Net-PCL.Threading/Collections/DictionaryThreadSafe.cs create mode 100644 src/ThunderDesign.Net-PCL.Threading/Interfaces/IDictionaryThreadSafe.cs diff --git a/src/ThunderDesign.Net-PCL.Threading/Collections/DictionaryThreadSafe.cs b/src/ThunderDesign.Net-PCL.Threading/Collections/DictionaryThreadSafe.cs new file mode 100644 index 0000000..c84cd40 --- /dev/null +++ b/src/ThunderDesign.Net-PCL.Threading/Collections/DictionaryThreadSafe.cs @@ -0,0 +1,242 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Text; +using ThunderDesign.Net.Threading.Interfaces; +using ThunderDesign.Net.Threading.Threading; + +namespace ThunderDesign.Net.Threading.Collections +{ + public class DictionaryThreadSafe : Dictionary, IDictionaryThreadSafe + { + #region constructors + public DictionaryThreadSafe() : base() { } + public DictionaryThreadSafe(int capacity) : base(capacity) { } + public DictionaryThreadSafe(IEqualityComparer comparer) : base(comparer) { } + public DictionaryThreadSafe(IDictionary dictionary) : base(dictionary) { } + public DictionaryThreadSafe(int capacity, IEqualityComparer comparer) : base(capacity, comparer) { } + public DictionaryThreadSafe(IDictionary dictionary, IEqualityComparer comparer) : base(dictionary, comparer) { } + #endregion + + #region properties + public new IEqualityComparer Comparer + { + get + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + return base.Comparer; + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + } + + public new int Count + { + get + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + return base.Count; + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + } + + public new KeyCollection Keys + { + get + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + return base.Keys; + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + } + + public new ValueCollection Values + { + get + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + return base.Values; + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + } + + public new TValue this[TKey key] + { + get + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + return base[key]; + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + set + { + _ReaderWriterNotifyLock.EnterWriteLock(); + try + { + base[key] = value; + } + finally + { + _ReaderWriterNotifyLock.ExitWriteLock(); + } + } + } + #endregion + + #region methods + public new virtual void Add(TKey key, TValue value) + { + _ReaderWriterNotifyLock.EnterWriteLock(); + try + { + base.Add(key, value); + } + finally + { + _ReaderWriterNotifyLock.ExitWriteLock(); + } + } + + public new virtual void Clear() + { + _ReaderWriterNotifyLock.EnterWriteLock(); + try + { + base.Clear(); + } + finally + { + _ReaderWriterNotifyLock.ExitWriteLock(); + } + } + + public new bool ContainsKey(TKey key) + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + return base.ContainsKey(key); + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + + public new bool ContainsValue(TValue value) + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + return base.ContainsValue(value); + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + + public new Enumerator GetEnumerator() + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + return base.GetEnumerator(); + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + + [System.Security.SecurityCritical] // auto-generated_required + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + base.GetObjectData(info, context); + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + + public override void OnDeserialization(Object sender) + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + base.OnDeserialization(sender); + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + + public new virtual bool Remove(TKey key) + { + bool result = false; + _ReaderWriterNotifyLock.EnterWriteLock(); + try + { + result = base.Remove(key); + } + finally + { + _ReaderWriterNotifyLock.ExitWriteLock(); + } + return result; + } + + public new bool TryGetValue(TKey key, out TValue value) + { + _ReaderWriterNotifyLock.EnterReadLock(); + try + { + return base.TryGetValue(key, out value); + } + finally + { + _ReaderWriterNotifyLock.ExitReadLock(); + } + } + #endregion + + #region variables + protected static readonly ReaderWriterNotifyLock _ReaderWriterNotifyLock = new ReaderWriterNotifyLock(); + + #endregion + } +} diff --git a/src/ThunderDesign.Net-PCL.Threading/Collections/ObservableDictionaryThreadSafe.cs b/src/ThunderDesign.Net-PCL.Threading/Collections/ObservableDictionaryThreadSafe.cs index 92447b6..296d93a 100644 --- a/src/ThunderDesign.Net-PCL.Threading/Collections/ObservableDictionaryThreadSafe.cs +++ b/src/ThunderDesign.Net-PCL.Threading/Collections/ObservableDictionaryThreadSafe.cs @@ -10,7 +10,7 @@ namespace ThunderDesign.Net.Threading.Collections { - public class ObservableDictionaryThreadSafe : Dictionary, IObservableDictionaryThreadSafe + public class ObservableDictionaryThreadSafe : DictionaryThreadSafe, IObservableDictionaryThreadSafe { #region constructors public ObservableDictionaryThreadSafe() : base() { } @@ -27,95 +27,15 @@ public ObservableDictionaryThreadSafe(IDictionary dictionary, IEqu #endregion #region properties - public new IEqualityComparer Comparer - { - get - { - _ReaderWriterNotifyLock.EnterReadLock(); - try - { - return base.Comparer; - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } - } - } - - public new int Count - { - get - { - _ReaderWriterNotifyLock.EnterReadLock(); - try - { - return base.Count; - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } - } - } - - public new KeyCollection Keys - { - get - { - _ReaderWriterNotifyLock.EnterReadLock(); - try - { - return base.Keys; - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } - } - } - - public new ValueCollection Values - { - get - { - _ReaderWriterNotifyLock.EnterReadLock(); - try - { - return base.Values; - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } - } - } - public new TValue this[TKey key] { get { - _ReaderWriterNotifyLock.EnterReadLock(); - try - { - return base[key]; - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } + return base[key]; } set { - _ReaderWriterNotifyLock.EnterWriteLock(); - try - { - base[key] = value; - } - finally - { - _ReaderWriterNotifyLock.ExitWriteLock(); - } + base[key] = value; OnPropertyChanged(nameof(Values)); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, key)); } @@ -123,138 +43,37 @@ public ObservableDictionaryThreadSafe(IDictionary dictionary, IEqu #endregion #region methods - public new void Add(TKey key, TValue value) + public override void Add(TKey key, TValue value) { - _ReaderWriterNotifyLock.EnterWriteLock(); - try - { - base.Add(key, value); - } - finally - { - _ReaderWriterNotifyLock.ExitWriteLock(); - } + base.Add(key, value); OnPropertyChanged(nameof(Keys)); OnPropertyChanged(nameof(Values)); OnPropertyChanged(nameof(Count)); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, key)); } - public new void Clear() + public override void Clear() { - _ReaderWriterNotifyLock.EnterWriteLock(); - try - { - base.Clear(); - } - finally - { - _ReaderWriterNotifyLock.ExitWriteLock(); - } + base.Clear(); OnPropertyChanged(nameof(Keys)); OnPropertyChanged(nameof(Values)); OnPropertyChanged(nameof(Count)); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } - public new bool ContainsKey(TKey key) + public override bool Remove(TKey key) { - _ReaderWriterNotifyLock.EnterReadLock(); - try + bool result = base.Remove(key); + if (result) { - return base.ContainsKey(key); - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } - } - - public new bool ContainsValue(TValue value) - { - _ReaderWriterNotifyLock.EnterReadLock(); - try - { - return base.ContainsValue(value); - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } - } - - public new Enumerator GetEnumerator() - { - _ReaderWriterNotifyLock.EnterReadLock(); - try - { - return base.GetEnumerator(); - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } - } - - [System.Security.SecurityCritical] // auto-generated_required - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - _ReaderWriterNotifyLock.EnterReadLock(); - try - { - base.GetObjectData(info, context); - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } - } - - public override void OnDeserialization(Object sender) - { - _ReaderWriterNotifyLock.EnterReadLock(); - try - { - base.OnDeserialization(sender); - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } - } - - public new bool Remove(TKey key) - { - bool result = false; - _ReaderWriterNotifyLock.EnterWriteLock(); - try - { - result = base.Remove(key); - } - finally - { - _ReaderWriterNotifyLock.ExitWriteLock(); + OnPropertyChanged(nameof(Keys)); + OnPropertyChanged(nameof(Values)); + OnPropertyChanged(nameof(Count)); + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, key)); } - OnPropertyChanged(nameof(Keys)); - OnPropertyChanged(nameof(Values)); - OnPropertyChanged(nameof(Count)); - OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, key)); return result; } - public new bool TryGetValue(TKey key, out TValue value) - { - _ReaderWriterNotifyLock.EnterReadLock(); - try - { - return base.TryGetValue(key, out value); - } - finally - { - _ReaderWriterNotifyLock.ExitReadLock(); - } - } - protected virtual void OnPropertyChanged(string propertyName) { this.NotifyPropertyChanged(PropertyChanged, propertyName); @@ -266,10 +85,5 @@ protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args } #endregion - - #region variables - protected static readonly ReaderWriterNotifyLock _ReaderWriterNotifyLock = new ReaderWriterNotifyLock(); - - #endregion } } diff --git a/src/ThunderDesign.Net-PCL.Threading/Interfaces/IDictionaryThreadSafe.cs b/src/ThunderDesign.Net-PCL.Threading/Interfaces/IDictionaryThreadSafe.cs new file mode 100644 index 0000000..488c48c --- /dev/null +++ b/src/ThunderDesign.Net-PCL.Threading/Interfaces/IDictionaryThreadSafe.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace ThunderDesign.Net.Threading.Interfaces +{ + public interface IDictionaryThreadSafe : IDictionary + { + } + + public interface IDictionaryThreadSafe : IDictionary, IDictionaryThreadSafe + { + } +} diff --git a/src/ThunderDesign.Net-PCL.Threading/Interfaces/IObservableDictionaryThreadSafe.cs b/src/ThunderDesign.Net-PCL.Threading/Interfaces/IObservableDictionaryThreadSafe.cs index ab65efd..f25be6b 100644 --- a/src/ThunderDesign.Net-PCL.Threading/Interfaces/IObservableDictionaryThreadSafe.cs +++ b/src/ThunderDesign.Net-PCL.Threading/Interfaces/IObservableDictionaryThreadSafe.cs @@ -7,11 +7,11 @@ namespace ThunderDesign.Net.Threading.Interfaces { - public interface IObservableDictionaryThreadSafe : IDictionary, INotifyCollectionChanged, INotifyPropertyChanged + public interface IObservableDictionaryThreadSafe : IDictionaryThreadSafe, INotifyCollectionChanged, INotifyPropertyChanged { } - public interface IObservableDictionaryThreadSafe : IDictionary, IObservableDictionaryThreadSafe + public interface IObservableDictionaryThreadSafe : IDictionaryThreadSafe, IObservableDictionaryThreadSafe { } }