/Collections/Specialized/ObservableDictionary.cs |
@@ -7,6 +7,7 @@ |
using System.Collections; |
using System.Collections.Generic; |
using System.Collections.Specialized; |
using System.Threading; |
|
namespace wasSharp.Collections.Specialized |
{ |
@@ -20,6 +21,7 @@ |
/// <typeparam name="V">the value type</typeparam> |
public class ObservableDictionary<K, V> : IDictionary<K, V>, INotifyCollectionChanged |
{ |
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); |
private readonly Dictionary<K, V> store = new Dictionary<K, V>(); |
|
public bool IsVirgin { get; private set; } = true; |
@@ -26,9 +28,20 @@ |
|
public V this[K key] |
{ |
get { return store[key]; } |
get |
{ |
SyncRoot.EnterReadLock(); |
var v = store[key]; |
SyncRoot.ExitReadLock(); |
return v; |
} |
|
set { store[key] = value; } |
set |
{ |
SyncRoot.EnterWriteLock(); |
store[key] = value; |
SyncRoot.ExitWriteLock(); |
} |
} |
|
public int Count => store.Count; |
@@ -35,13 +48,33 @@ |
|
public bool IsReadOnly => false; |
|
public ICollection<K> Keys => store.Keys; |
public ICollection<K> Keys |
{ |
get |
{ |
SyncRoot.EnterReadLock(); |
var v = store.Keys; |
SyncRoot.ExitReadLock(); |
return v; |
} |
} |
|
public ICollection<V> Values => store.Values; |
public ICollection<V> Values |
{ |
get |
{ |
SyncRoot.EnterReadLock(); |
var v = store.Values; |
SyncRoot.ExitReadLock(); |
return v; |
} |
} |
|
public void Add(KeyValuePair<K, V> item) |
{ |
SyncRoot.EnterWriteLock(); |
((IDictionary<K, V>)store).Add(item); |
SyncRoot.ExitWriteLock(); |
IsVirgin = false; |
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)); |
} |
@@ -48,7 +81,9 @@ |
|
public void Add(K key, V value) |
{ |
SyncRoot.EnterWriteLock(); |
store.Add(key, value); |
SyncRoot.ExitWriteLock(); |
IsVirgin = false; |
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, |
new KeyValuePair<K, V>(key, value))); |
@@ -56,7 +91,9 @@ |
|
public void Clear() |
{ |
SyncRoot.EnterWriteLock(); |
store.Clear(); |
SyncRoot.ExitWriteLock(); |
if (!IsVirgin) |
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); |
IsVirgin = false; |
@@ -64,27 +101,40 @@ |
|
public bool Contains(KeyValuePair<K, V> item) |
{ |
return ((IDictionary<K, V>)store).Contains(item); |
SyncRoot.EnterReadLock(); |
var c = ((IDictionary<K, V>)store).Contains(item); |
SyncRoot.ExitReadLock(); |
return c; |
} |
|
public bool ContainsKey(K key) |
{ |
return store.ContainsKey(key); |
SyncRoot.EnterReadLock(); |
var c = store.ContainsKey(key); |
SyncRoot.ExitReadLock(); |
return c; |
} |
|
public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex) |
{ |
SyncRoot.EnterReadLock(); |
((IDictionary<K, V>)store).CopyTo(array, arrayIndex); |
SyncRoot.ExitReadLock(); |
} |
|
public IEnumerator<KeyValuePair<K, V>> GetEnumerator() |
{ |
return ((IDictionary<K, V>)store).GetEnumerator(); |
SyncRoot.EnterReadLock(); |
var enumerator = ((IDictionary<K, V>)store).GetEnumerator(); |
SyncRoot.ExitReadLock(); |
return enumerator; |
} |
|
public bool Remove(KeyValuePair<K, V> item) |
{ |
SyncRoot.EnterWriteLock(); |
var removed = ((IDictionary<K, V>)store).Remove(item); |
SyncRoot.ExitWriteLock(); |
IsVirgin = false; |
if (removed) |
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item)); |
@@ -94,10 +144,12 @@ |
public bool Remove(K key) |
{ |
KeyValuePair<K, V> item; |
SyncRoot.EnterWriteLock(); |
if (store.ContainsKey(key)) |
item = new KeyValuePair<K, V>(key, store[key]); |
|
var removed = store.Remove(key); |
SyncRoot.ExitWriteLock(); |
IsVirgin = false; |
if (removed) |
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item)); |
@@ -106,12 +158,18 @@ |
|
public bool TryGetValue(K key, out V value) |
{ |
return store.TryGetValue(key, out value); |
SyncRoot.EnterReadLock(); |
var c = store.TryGetValue(key, out value); |
SyncRoot.ExitReadLock(); |
return c; |
} |
|
IEnumerator IEnumerable.GetEnumerator() |
{ |
return ((IDictionary<K, V>)store).GetEnumerator(); |
SyncRoot.EnterReadLock(); |
var enumerator = ((IDictionary<K, V>)store).GetEnumerator(); |
SyncRoot.ExitReadLock(); |
return enumerator; |
} |
|
public event NotifyCollectionChangedEventHandler CollectionChanged; |