wasSharp

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 43  →  ?path2? @ 44
/Collections/Specialized/ObservableDictionary.cs
@@ -21,7 +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 ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private readonly Dictionary<K, V> store = new Dictionary<K, V>();
 
public bool IsVirgin { get; private set; } = true;
@@ -30,17 +30,28 @@
{
get
{
SyncRoot.EnterReadLock();
var v = store[key];
SyncRoot.ExitReadLock();
return v;
_lock.EnterReadLock();
try
{
return store[key];
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
set
{
SyncRoot.EnterWriteLock();
store[key] = value;
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
store[key] = value;
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
}
 
@@ -52,10 +63,15 @@
{
get
{
SyncRoot.EnterReadLock();
var v = store.Keys;
SyncRoot.ExitReadLock();
return v;
_lock.EnterReadLock();
try
{
return store.Keys;
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
}
 
@@ -63,18 +79,29 @@
{
get
{
SyncRoot.EnterReadLock();
var v = store.Values;
SyncRoot.ExitReadLock();
return v;
_lock.EnterReadLock();
try
{
return store.Values;
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
}
 
public void Add(KeyValuePair<K, V> item)
{
SyncRoot.EnterWriteLock();
((IDictionary<K, V>)store).Add(item);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
((IDictionary<K, V>) store).Add(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
IsVirgin = false;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}
@@ -81,9 +108,15 @@
 
public void Add(K key, V value)
{
SyncRoot.EnterWriteLock();
store.Add(key, value);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
store.Add(key, value);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
IsVirgin = false;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,
new KeyValuePair<K, V>(key, value)));
@@ -91,9 +124,15 @@
 
public void Clear()
{
SyncRoot.EnterWriteLock();
store.Clear();
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
store.Clear();
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
if (!IsVirgin)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
IsVirgin = false;
@@ -101,40 +140,72 @@
 
public bool Contains(KeyValuePair<K, V> item)
{
SyncRoot.EnterReadLock();
var c = ((IDictionary<K, V>)store).Contains(item);
SyncRoot.ExitReadLock();
return c;
_lock.EnterReadLock();
try
{
return ((IDictionary<K, V>) store).Contains(item);
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
public bool ContainsKey(K key)
{
SyncRoot.EnterReadLock();
var c = store.ContainsKey(key);
SyncRoot.ExitReadLock();
return c;
_lock.EnterReadLock();
try
{
return store.ContainsKey(key);
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
{
SyncRoot.EnterReadLock();
((IDictionary<K, V>)store).CopyTo(array, arrayIndex);
SyncRoot.ExitReadLock();
_lock.EnterReadLock();
try
{
((IDictionary<K, V>) store).CopyTo(array, arrayIndex);
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
SyncRoot.EnterReadLock();
var enumerator = ((IDictionary<K, V>)store).GetEnumerator();
SyncRoot.ExitReadLock();
return enumerator;
_lock.EnterReadLock();
try
{
using (var enumerator = ((IDictionary<K, V>)store).GetEnumerator())
{
while (enumerator.MoveNext())
yield return enumerator.Current;
}
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
public bool Remove(KeyValuePair<K, V> item)
{
SyncRoot.EnterWriteLock();
var removed = ((IDictionary<K, V>)store).Remove(item);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
bool removed;
try
{
removed = ((IDictionary<K, V>) store).Remove(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
IsVirgin = false;
if (removed)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
@@ -144,12 +215,19 @@
public bool Remove(K key)
{
KeyValuePair<K, V> item;
SyncRoot.EnterWriteLock();
if (store.ContainsKey(key))
item = new KeyValuePair<K, V>(key, store[key]);
_lock.EnterWriteLock();
bool removed;
try
{
if (store.ContainsKey(key))
item = new KeyValuePair<K, V>(key, store[key]);
 
var removed = store.Remove(key);
SyncRoot.ExitWriteLock();
removed = store.Remove(key);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
IsVirgin = false;
if (removed)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
@@ -158,18 +236,32 @@
 
public bool TryGetValue(K key, out V value)
{
SyncRoot.EnterReadLock();
var c = store.TryGetValue(key, out value);
SyncRoot.ExitReadLock();
return c;
_lock.EnterReadLock();
try
{
return store.TryGetValue(key, out value);
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
IEnumerator IEnumerable.GetEnumerator()
{
SyncRoot.EnterReadLock();
var enumerator = ((IDictionary<K, V>)store).GetEnumerator();
SyncRoot.ExitReadLock();
return enumerator;
_lock.EnterReadLock();
try
{
using (var enumerator = ((IDictionary<K, V>)store).GetEnumerator())
{
while (enumerator.MoveNext())
yield return enumerator.Current;
}
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
public event NotifyCollectionChangedEventHandler CollectionChanged;