wasSharp

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 39  →  ?path2? @ 38
/Collections/Specialized/ConcurrentLazyList.cs
@@ -0,0 +1,176 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
 
// http://www.fallingcanbedeadly.com/posts/crazy-extention-methods-tolazylist/
 
namespace wasSharp.Collections.Specialized
{
public class ConcurrentLazyList<T> : IList<T>, IDisposable
{
public ConcurrentLazyList(IEnumerable<T> list)
{
syncRoot.EnterReadLock();
_enumerator = list.GetEnumerator();
syncRoot.ExitReadLock();
_isFinished = false;
_cached = new List<T>();
}
 
public T this[int index]
{
get
{
if (index < 0)
throw new ArgumentOutOfRangeException("index");
 
while (_cached.Count <= index && !_isFinished)
{
syncRoot.EnterReadLock();
GetNext();
syncRoot.ExitReadLock();
}
var cached = _cached[index];
return cached;
}
set
{
throw new NotSupportedException();
}
}
 
public int Count
{
get
{
syncRoot.EnterWriteLock();
Finish();
syncRoot.ExitWriteLock();
return _cached.Count;
}
}
 
public IEnumerator<T> GetEnumerator()
{
int current = 0;
 
while (current < _cached.Count || !_isFinished)
{
if (current == _cached.Count)
{
syncRoot.EnterReadLock();
GetNext();
syncRoot.ExitReadLock();
}
if (current != _cached.Count)
yield return _cached[current];
current++;
}
}
 
public void Dispose()
{
syncRoot.EnterWriteLock();
_enumerator.Dispose();
syncRoot.ExitWriteLock();
_isFinished = true;
}
 
public int IndexOf(T item)
{
int result = _cached.IndexOf(item);
while (result == -1 && !_isFinished)
{
syncRoot.EnterReadLock();
GetNext();
syncRoot.ExitReadLock();
if (_cached.Last().Equals(item))
result = _cached.Count - 1;
}
 
return result;
}
 
public void Insert(int index, T item)
{
throw new NotSupportedException();
}
 
public void RemoveAt(int index)
{
throw new NotSupportedException();
}
 
public void Add(T item)
{
throw new NotSupportedException();
}
 
public void Clear()
{
throw new NotSupportedException();
}
 
public bool Contains(T item)
{
syncRoot.EnterReadLock();
var contains = IndexOf(item) != -1;
syncRoot.ExitReadLock();
return contains;
}
 
public void CopyTo(T[] array, int arrayIndex)
{
syncRoot.EnterReadLock();
foreach (var item in this)
array[arrayIndex++] = item;
syncRoot.ExitReadLock();
}
 
public bool IsReadOnly => true;
 
public bool Remove(T item)
{
throw new NotSupportedException();
}
 
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
 
private void GetNext()
{
if (!_isFinished)
{
if (_enumerator.MoveNext())
{
_cached.Add(_enumerator.Current);
}
else
{
_isFinished = true;
_enumerator.Dispose();
}
}
}
 
private void Finish()
{
while (!_isFinished)
GetNext();
}
 
private readonly List<T> _cached;
private readonly IEnumerator<T> _enumerator;
private bool _isFinished;
private ReaderWriterLockSlim syncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
}
}
/Collections/Specialized/MultiKeyDictionary.cs
@@ -5,94 +5,61 @@
///////////////////////////////////////////////////////////////////////////
// Based on the work of Herman Schoenfeld
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
 
namespace wasSharp.Collections.Specialized
{
public class MultiKeyDictionary<K1, K2, V> : Dictionary<K1, Dictionary<K2, V>>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
public V this[K1 key1, K2 key2]
{
get
{
SyncRoot.EnterReadLock();
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2))
{
SyncRoot.ExitReadLock();
return default(V);
}
var v = base[key1][key2];
SyncRoot.ExitReadLock();
return v;
throw new ArgumentOutOfRangeException();
return base[key1][key2];
}
set
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new Dictionary<K2, V>();
 
this[key1][key2] = value;
SyncRoot.ExitWriteLock();
}
}
 
public new IEnumerable<V> Values
{
get
{
SyncRoot.EnterReadLock();
var v = base.Values.SelectMany(baseDict => baseDict.Keys, (baseDict, baseKey) => baseDict[baseKey]);
SyncRoot.ExitReadLock();
return v;
}
}
public new IEnumerable<V> Values =>
base.Values.SelectMany(baseDict => baseDict.Keys, (baseDict, baseKey) => baseDict[baseKey]);
 
public void Add(K1 key1, K2 key2, V value)
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new Dictionary<K2, V>();
 
this[key1][key2] = value;
SyncRoot.ExitWriteLock();
}
 
public void Remove(K1 key1, K2 key2)
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2))
{
SyncRoot.ExitWriteLock();
return;
}
this[key1].Remove(key2);
Remove(key1);
SyncRoot.ExitWriteLock();
}
 
public bool ContainsKey(K1 key1, K2 key2)
{
SyncRoot.EnterReadLock();
var c = ContainsKey(key1) && this[key1].ContainsKey(key2);
SyncRoot.ExitReadLock();
return c;
return ContainsKey(key1) && this[key1].ContainsKey(key2);
}
 
public bool TryGetValue(K1 key1, K2 key2, out V value)
{
SyncRoot.EnterReadLock();
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2))
{
SyncRoot.ExitReadLock();
value = default(V);
return false;
}
value = base[key1][key2];
SyncRoot.ExitReadLock();
return true;
}
}
@@ -99,69 +66,46 @@
 
public class MultiKeyDictionary<K1, K2, K3, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, V>>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
public V this[K1 key1, K2 key2, K3 key3]
{
get
{
SyncRoot.EnterReadLock();
var v = ContainsKey(key1) ? this[key1][key2, key3] : default(V);
SyncRoot.ExitReadLock();
return v;
}
get { return ContainsKey(key1) ? this[key1][key2, key3] : default(V); }
set
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, V>();
this[key1][key2, key3] = value;
SyncRoot.ExitWriteLock();
}
}
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3)
{
SyncRoot.EnterReadLock();
var c = ContainsKey(key1) && this[key1].ContainsKey(key2, key3);
SyncRoot.ExitReadLock();
return c;
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3);
}
 
public void Add(K1 key1, K2 key2, K3 key3, V value)
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, V>();
this[key1][key2, key3] = value;
SyncRoot.ExitWriteLock();
}
 
public void Remove(K1 key1, K2 key2, K3 key3)
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2, key3))
{
SyncRoot.ExitWriteLock();
return;
}
this[key1][key2].Remove(key3);
this[key1].Remove(key2);
Remove(key1);
SyncRoot.ExitWriteLock();
}
 
public bool TryGetValue(K1 key1, K2 key2, K3 key3, out V value)
{
SyncRoot.EnterReadLock();
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2, key3))
{
SyncRoot.ExitReadLock();
value = default(V);
return false;
}
value = base[key1][key2, key3];
SyncRoot.ExitReadLock();
return true;
}
}
@@ -168,65 +112,39 @@
 
public class MultiKeyDictionary<K1, K2, K3, K4, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, V>>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
public V this[K1 key1, K2 key2, K3 key3, K4 key4]
{
get
{
SyncRoot.EnterReadLock();
var v = ContainsKey(key1) ? this[key1][key2, key3, key4] : default(V);
SyncRoot.ExitReadLock();
return v;
}
get { return ContainsKey(key1) ? this[key1][key2, key3, key4] : default(V); }
set
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, K4, V>();
this[key1][key2, key3, key4] = value;
SyncRoot.ExitWriteLock();
}
}
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4)
{
SyncRoot.EnterReadLock();
var c = ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4);
SyncRoot.ExitReadLock();
return c;
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4);
}
}
 
public class MultiKeyDictionary<K1, K2, K3, K4, K5, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, V>>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5]
{
get
{
SyncRoot.EnterReadLock();
var v = ContainsKey(key1) ? this[key1][key2, key3, key4, key5] : default(V);
SyncRoot.ExitReadLock();
return v;
}
get { return ContainsKey(key1) ? this[key1][key2, key3, key4, key5] : default(V); }
set
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, V>();
this[key1][key2, key3, key4, key5] = value;
SyncRoot.ExitWriteLock();
}
}
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5)
{
SyncRoot.EnterReadLock();
var c = ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5);
SyncRoot.ExitReadLock();
return c;
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5);
}
}
 
@@ -233,33 +151,20 @@
public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, V> :
Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, V>>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6]
{
get
{
SyncRoot.EnterReadLock();
var v = ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6] : default(V);
SyncRoot.ExitReadLock();
return v;
}
get { return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6] : default(V); }
set
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, V>();
this[key1][key2, key3, key4, key5, key6] = value;
SyncRoot.ExitWriteLock();
}
}
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6)
{
SyncRoot.EnterReadLock();
var c = ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6);
SyncRoot.ExitReadLock();
return c;
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6);
}
}
 
@@ -266,33 +171,20 @@
public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, K7, V> :
Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, K7, V>>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7]
{
get
{
SyncRoot.EnterReadLock();
var v = ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7] : default(V);
SyncRoot.ExitReadLock();
return v;
}
get { return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7] : default(V); }
set
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, K7, V>();
this[key1][key2, key3, key4, key5, key6, key7] = value;
SyncRoot.ExitWriteLock();
}
}
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7)
{
SyncRoot.EnterReadLock();
var c = ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7);
SyncRoot.ExitReadLock();
return c;
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7);
}
}
 
@@ -299,33 +191,20 @@
public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, K7, K8, V> :
Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, V>>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8]
{
get
{
SyncRoot.EnterReadLock();
var v = ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7, key8] : default(V);
SyncRoot.ExitReadLock();
return v;
}
get { return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7, key8] : default(V); }
set
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, V>();
this[key1][key2, key3, key4, key5, key6, key7, key8] = value;
SyncRoot.ExitWriteLock();
}
}
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8)
{
SyncRoot.EnterReadLock();
var c = ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8);
SyncRoot.ExitReadLock();
return c;
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8);
}
}
 
@@ -332,33 +211,20 @@
public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, K7, K8, K9, V> :
Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, V>>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9]
{
get
{
SyncRoot.EnterReadLock();
var v = ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7, key8, key9] : default(V);
SyncRoot.ExitReadLock();
return v;
}
get { return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7, key8, key9] : default(V); }
set
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, V>();
this[key1][key2, key3, key4, key5, key6, key7, key8, key9] = value;
SyncRoot.ExitWriteLock();
}
}
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9)
{
SyncRoot.EnterReadLock();
var c = ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9);
SyncRoot.ExitReadLock();
return c;
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9);
}
}
 
@@ -365,24 +231,17 @@
public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, V> :
Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, K10, V>>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9, K10 key10]
{
get
{
SyncRoot.EnterReadLock();
var v = ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7, key8, key9, key10] : default(V);
SyncRoot.ExitReadLock();
return v;
return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7, key8, key9, key10] : default(V);
}
set
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, K10, V>();
this[key1][key2, key3, key4, key5, key6, key7, key8, key9, key10] = value;
SyncRoot.ExitWriteLock();
}
}
 
@@ -389,11 +248,8 @@
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9,
K10 key10)
{
SyncRoot.EnterReadLock();
var c = ContainsKey(key1) &&
return ContainsKey(key1) &&
this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9, key10);
SyncRoot.ExitReadLock();
return c;
}
}
 
@@ -400,27 +256,20 @@
public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, V> :
Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, V>>
{
private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
public V this[
K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9, K10 key10, K11 key11]
{
get
{
SyncRoot.EnterReadLock();
var v = ContainsKey(key1)
return ContainsKey(key1)
? this[key1][key2, key3, key4, key5, key6, key7, key8, key9, key10, key11]
: default(V);
SyncRoot.ExitReadLock();
return v;
}
set
{
SyncRoot.EnterWriteLock();
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, V>();
this[key1][key2, key3, key4, key5, key6, key7, key8, key9, key10, key11] = value;
SyncRoot.ExitWriteLock();
}
}
 
@@ -427,11 +276,8 @@
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9,
K10 key10, K11 key11)
{
SyncRoot.EnterReadLock();
var c = ContainsKey(key1) &&
return ContainsKey(key1) &&
this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9, key10, key11);
SyncRoot.ExitReadLock();
return c;
}
}
}
/Collections/Specialized/ObservableDictionary.cs
@@ -7,7 +7,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Threading;
 
namespace wasSharp.Collections.Specialized
{
@@ -21,7 +20,6 @@
/// <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;
@@ -28,20 +26,9 @@
 
public V this[K key]
{
get
{
SyncRoot.EnterReadLock();
var v = store[key];
SyncRoot.ExitReadLock();
return v;
}
get { return store[key]; }
 
set
{
SyncRoot.EnterWriteLock();
store[key] = value;
SyncRoot.ExitWriteLock();
}
set { store[key] = value; }
}
 
public int Count => store.Count;
@@ -48,33 +35,13 @@
 
public bool IsReadOnly => false;
 
public ICollection<K> Keys
{
get
{
SyncRoot.EnterReadLock();
var v = store.Keys;
SyncRoot.ExitReadLock();
return v;
}
}
public ICollection<K> Keys => store.Keys;
 
public ICollection<V> Values
{
get
{
SyncRoot.EnterReadLock();
var v = store.Values;
SyncRoot.ExitReadLock();
return v;
}
}
public ICollection<V> Values => store.Values;
 
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));
}
@@ -81,9 +48,7 @@
 
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)));
@@ -91,9 +56,7 @@
 
public void Clear()
{
SyncRoot.EnterWriteLock();
store.Clear();
SyncRoot.ExitWriteLock();
if (!IsVirgin)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
IsVirgin = false;
@@ -101,40 +64,27 @@
 
public bool Contains(KeyValuePair<K, V> item)
{
SyncRoot.EnterReadLock();
var c = ((IDictionary<K, V>)store).Contains(item);
SyncRoot.ExitReadLock();
return c;
return ((IDictionary<K, V>)store).Contains(item);
}
 
public bool ContainsKey(K key)
{
SyncRoot.EnterReadLock();
var c = store.ContainsKey(key);
SyncRoot.ExitReadLock();
return c;
return store.ContainsKey(key);
}
 
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()
{
SyncRoot.EnterReadLock();
var enumerator = ((IDictionary<K, V>)store).GetEnumerator();
SyncRoot.ExitReadLock();
return enumerator;
return ((IDictionary<K, V>)store).GetEnumerator();
}
 
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));
@@ -144,12 +94,10 @@
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));
@@ -158,18 +106,12 @@
 
public bool TryGetValue(K key, out V value)
{
SyncRoot.EnterReadLock();
var c = store.TryGetValue(key, out value);
SyncRoot.ExitReadLock();
return c;
return store.TryGetValue(key, out value);
}
 
IEnumerator IEnumerable.GetEnumerator()
{
SyncRoot.EnterReadLock();
var enumerator = ((IDictionary<K, V>)store).GetEnumerator();
SyncRoot.ExitReadLock();
return enumerator;
return ((IDictionary<K, V>)store).GetEnumerator();
}
 
public event NotifyCollectionChangedEventHandler CollectionChanged;
/Collections/Specialized/ObservableHashSet.cs
@@ -5,7 +5,6 @@
///////////////////////////////////////////////////////////////////////////
 
using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
@@ -22,14 +21,11 @@
/// <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 HashSet<T> store = new HashSet<T>();
 
public ObservableHashSet(HashSet<T> set)
{
SyncRoot.EnterWriteLock();
UnionWith(set);
SyncRoot.ExitWriteLock();
}
 
public ObservableHashSet()
@@ -38,23 +34,17 @@
 
public ObservableHashSet(T item)
{
SyncRoot.EnterWriteLock();
Add(item);
SyncRoot.ExitWriteLock();
}
 
public ObservableHashSet(ObservableHashSet<T> other)
{
SyncRoot.EnterWriteLock();
UnionWith(other);
SyncRoot.ExitWriteLock();
}
 
public ObservableHashSet(IEnumerable<T> list)
{
SyncRoot.EnterWriteLock();
UnionWith(list);
SyncRoot.ExitWriteLock();
}
 
public bool IsVirgin { get; private set; } = true;
@@ -61,25 +51,17 @@
 
public IEnumerator<T> GetEnumerator()
{
SyncRoot.EnterReadLock();
var enumerator = store.GetEnumerator();
SyncRoot.ExitReadLock();
return enumerator;
return store.GetEnumerator();
}
 
IEnumerator IEnumerable.GetEnumerator()
{
SyncRoot.EnterReadLock();
var enumerator = GetEnumerator();
SyncRoot.ExitReadLock();
return enumerator;
return GetEnumerator();
}
 
public void Add(T item)
{
SyncRoot.EnterWriteLock();
store.Add(item);
SyncRoot.ExitWriteLock();
IsVirgin = false;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}
@@ -86,9 +68,7 @@
 
public void Clear()
{
SyncRoot.EnterWriteLock();
store.Clear();
SyncRoot.ExitWriteLock();
if (!IsVirgin)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
IsVirgin = false;
@@ -96,24 +76,17 @@
 
public bool Contains(T item)
{
SyncRoot.EnterReadLock();
var contains = store.Contains(item);
SyncRoot.ExitReadLock();
return contains;
return store.Contains(item);
}
 
public void CopyTo(T[] array, int arrayIndex)
{
SyncRoot.EnterReadLock();
store.CopyTo(array, arrayIndex);
SyncRoot.ExitReadLock();
}
 
public bool Remove(T item)
{
SyncRoot.EnterWriteLock();
var removed = store.Remove(item);
SyncRoot.ExitWriteLock();
IsVirgin = false;
if (removed)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
@@ -129,9 +102,7 @@
public void UnionWith(IEnumerable<T> list)
{
var added = new List<T>(list.Except(store));
SyncRoot.EnterWriteLock();
store.UnionWith(added);
SyncRoot.ExitWriteLock();
if (!IsVirgin && added.Any())
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, added));
IsVirgin = false;
@@ -145,9 +116,7 @@
public void ExceptWith(IEnumerable<T> list)
{
var removed = new List<T>(list.Intersect(store));
SyncRoot.EnterWriteLock();
store.ExceptWith(removed);
SyncRoot.ExitWriteLock();
if (!IsVirgin && removed.Any())
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,
removed));
@@ -157,9 +126,7 @@
public void RemoveWhere(Func<T, bool> func)
{
var removed = new List<T>(store.Where(func));
SyncRoot.EnterWriteLock();
store.ExceptWith(removed);
SyncRoot.ExitWriteLock();
if (!IsVirgin && removed.Any())
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,
removed));
@@ -168,10 +135,7 @@
 
public IEnumerable<T> AsEnumerable()
{
SyncRoot.EnterWriteLock();
var enumerable = store.AsEnumerable();
SyncRoot.ExitWriteLock();
return enumerable;
return store.AsEnumerable();
}
}
}
/Collections/Utilities/CollectionExtensions.cs
@@ -98,5 +98,10 @@
}
return dict;
}
 
public static IList<T> ToLazyList<T>(this IEnumerable<T> list)
{
return new ConcurrentLazyList<T>(list);
}
}
}
/Collections/Generic/SerializableDictionary.cs
@@ -72,12 +72,41 @@
}
}
 
/// <summary>
/// Deep-clones the serializable dictionary.
/// </summary>
/// <returns>a deep clone of the original dictionary</returns>
public SerializableDictionary<TKey, TValue> Clone()
{
SerializableDictionary<TKey, TValue> clone;
try
{
using (var memoryStream = new MemoryStream())
{
new XmlSerializer(
typeof(SerializableDictionary<TKey, TValue>), new XmlRootAttribute(DictionaryNodeName))
.Serialize(memoryStream, this);
memoryStream.Position = 0;
clone = (SerializableDictionary<TKey, TValue>)
new XmlSerializer(
typeof(SerializableDictionary<TKey, TValue>), new XmlRootAttribute(DictionaryNodeName))
.Deserialize(memoryStream);
}
}
/* cloning failed so return an empty dictionary */
catch (Exception)
{
clone = new SerializableDictionary<TKey, TValue>();
}
return clone;
}
 
#region Constants
 
public readonly string DictionaryNodeName = @"Dictionary";
public readonly string ItemNodeName = @"Item";
public readonly string KeyNodeName = @"Key";
public readonly string ValueNodeName = @"Value";
public string DictionaryNodeName { get; set; } = "Dictionary";
public string ItemNodeName { get; set; } = "Item";
public string KeyNodeName { get; set; } = "Key";
public string ValueNodeName { get; set; } = "Value";
 
#endregion Constants