wasSharp

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 43  →  ?path2? @ 44
/Collections/Specialized/ObservableHashSet.cs
@@ -22,14 +22,20 @@
/// <typeparam name="T">the object type</typeparam>
public class ObservableHashSet<T> : ICollection<T>, INotifyCollectionChanged, IEnumerable<T>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private readonly HashSet<T> store = new HashSet<T>();
 
public ObservableHashSet(HashSet<T> set)
{
SyncRoot.EnterWriteLock();
UnionWith(set);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
UnionWith(set);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
 
public ObservableHashSet()
@@ -38,23 +44,41 @@
 
public ObservableHashSet(T item)
{
SyncRoot.EnterWriteLock();
Add(item);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
Add(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
 
public ObservableHashSet(ObservableHashSet<T> other)
{
SyncRoot.EnterWriteLock();
UnionWith(other);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
UnionWith(other);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
 
public ObservableHashSet(IEnumerable<T> list)
{
SyncRoot.EnterWriteLock();
UnionWith(list);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
UnionWith(list);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
 
public bool IsVirgin { get; private set; } = true;
@@ -61,25 +85,49 @@
 
public IEnumerator<T> GetEnumerator()
{
SyncRoot.EnterReadLock();
var enumerator = store.GetEnumerator();
SyncRoot.ExitReadLock();
return enumerator;
_lock.EnterReadLock();
try
{
using (var enumerator = store.GetEnumerator())
{
while (enumerator.MoveNext())
yield return enumerator.Current;
}
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
IEnumerator IEnumerable.GetEnumerator()
{
SyncRoot.EnterReadLock();
var enumerator = GetEnumerator();
SyncRoot.ExitReadLock();
return enumerator;
_lock.EnterReadLock();
try
{
using (var enumerator = store.GetEnumerator())
{
while (enumerator.MoveNext())
yield return enumerator.Current;
}
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
public void Add(T item)
{
SyncRoot.EnterWriteLock();
store.Add(item);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
store.Add(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
IsVirgin = false;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}
@@ -86,9 +134,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;
@@ -96,24 +150,42 @@
 
public bool Contains(T item)
{
SyncRoot.EnterReadLock();
var contains = store.Contains(item);
SyncRoot.ExitReadLock();
return contains;
_lock.EnterReadLock();
try
{
return store.Contains(item);
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
public void CopyTo(T[] array, int arrayIndex)
{
SyncRoot.EnterReadLock();
store.CopyTo(array, arrayIndex);
SyncRoot.ExitReadLock();
_lock.EnterReadLock();
try
{
store.CopyTo(array, arrayIndex);
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
 
public bool Remove(T item)
{
SyncRoot.EnterWriteLock();
var removed = store.Remove(item);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
bool removed;
try
{
removed = store.Remove(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
IsVirgin = false;
if (removed)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
@@ -129,9 +201,15 @@
public void UnionWith(IEnumerable<T> list)
{
var added = new List<T>(list.Except(store));
SyncRoot.EnterWriteLock();
store.UnionWith(added);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
store.UnionWith(added);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
if (!IsVirgin && added.Any())
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, added));
IsVirgin = false;
@@ -145,9 +223,15 @@
public void ExceptWith(IEnumerable<T> list)
{
var removed = new List<T>(list.Intersect(store));
SyncRoot.EnterWriteLock();
store.ExceptWith(removed);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
store.ExceptWith(removed);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
if (!IsVirgin && removed.Any())
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,
removed));
@@ -157,9 +241,15 @@
public void RemoveWhere(Func<T, bool> func)
{
var removed = new List<T>(store.Where(func));
SyncRoot.EnterWriteLock();
store.ExceptWith(removed);
SyncRoot.ExitWriteLock();
_lock.EnterWriteLock();
try
{
store.ExceptWith(removed);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
if (!IsVirgin && removed.Any())
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,
removed));
@@ -168,10 +258,15 @@
 
public IEnumerable<T> AsEnumerable()
{
SyncRoot.EnterWriteLock();
var enumerable = store.AsEnumerable();
SyncRoot.ExitWriteLock();
return enumerable;
_lock.EnterWriteLock();
try
{
return store.AsEnumerable();
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
}
}