问题描述
我想在ConcurrentDictionary的精神来实现ConcurrentHashSet,采取的办法是使用一个内部的支持ConcurrentDictionary,写小委派的方法,这是我有多远了,但还有集合论方法是我坚持的,尤其。我不知道如果我可以用一个foreach,但仍不能违反并发
公共类ConcurrentHashSet< TElement> :的ISet< TElement>
{
私人只读ConcurrentDictionary< TElement,对象> _内部;
公共ConcurrentHashSet(IEnumerable的< TElement>元素= NULL)
{
_internal =新ConcurrentDictionary< TElement,对象>();
如果(元素!= NULL)
UnionWith(元素);
}
公共无效UnionWith(IEnumerable的< TElement>其他)
{
如果(其他== NULL)抛出新ArgumentNullException(其他);
的foreach(在其他变种otherElement)
添加(otherElement);
}
公共无效IntersectWith(IEnumerable的< TElement>其他)
{
抛出新的NotImplementedException();
}
公共无效ExceptWith(IEnumerable的< TElement>其他)
{
抛出新的NotImplementedException();
}
公共无效SymmetricExceptWith(IEnumerable的< TElement>其他)
{
抛出新的NotImplementedException();
}
公共BOOL IsSubsetOf(IEnumerable的< TElement>其他)
{
抛出新的NotImplementedException();
}
公共BOOL IsSupersetOf(IEnumerable的< TElement>其他)
{
抛出新的NotImplementedException();
}
公共BOOL IsProperSupersetOf(IEnumerable的< TElement>其他)
{
抛出新的NotImplementedException();
}
公共BOOL IsProperSubsetOf(IEnumerable的< TElement>其他)
{
抛出新的NotImplementedException();
}
公共BOOL重叠(IEnumerable的< TElement>其他)
{
返回other.Any(otherElement => _internal.ContainsKey(otherElement));
}
公共BOOL SetEquals(IEnumerable的< TElement>其他)
{
INT otherCount = 0;
INT thisCount =计数;
的foreach(在其他变种otherElement)
{
otherCount ++;
如果(!_internal.ContainsKey(otherElement))
返回false;
}
返回otherCount == thisCount;
}
公共BOOL添加(TElement项)
{
返回_internal.TryAdd(项目,NULL);
}
公共无效清除()
{
_internal.Clear();
}
//我不知道这里是否能正确fullfills合同
无效的ICollection< TElement>。新增(TElement项)
{
添加(项目);
}
公共BOOL包含(TElement项)
{
返回_internal.ContainsKey(项目);
}
公共无效CopyTo从(TElement []数组,INT arrayIndex)
{
_internal.Keys.CopyTo(阵列,arrayIndex);
}
公共BOOL删除(TElement项)
{
反对忽视;
返回_internal.TryRemove(项目,淘汰忽略);
}
公众诠释计数
{
{返回_internal.Count; }
}
公共BOOL的IsReadOnly
{
获得{返回false; }
}
公众的IEnumerator< TElement>的GetEnumerator()
{
返回_internal.Keys.GetEnumerator();
}
IEnumerator的IEnumerable.GetEnumerator()
{
返回的GetEnumerator();
}
}
我只是碰到了类似的情况(我感兴趣的快速增加和包含与删除)并实施这个傻逼:
使用System.Collections.Generic;
使用的System.Threading;
命名空间BlahBlah.Utilities
{
公共类ConcurrentHashSet< T> :IDisposable接口
{
私人只读ReaderWriterLockSlim _lock =新ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
私人只读的HashSet< T> _hashSet =新的HashSet< T>();
T>的ICollection&LT的#地区的执行情况; ... ISH
公共BOOL添加(T项)
{
尝试
{
_lock.EnterWriteLock();
返回_hashSet.Add(项目);
}
最后
{
如果(_lock.IsWriteLockHeld)_lock.ExitWriteLock();
}
}
公共无效清除()
{
尝试
{
_lock.EnterWriteLock();
_hashSet.Clear();
}
最后
{
如果(_lock.IsWriteLockHeld)_lock.ExitWriteLock();
}
}
公共BOOL包含(T项)
{
尝试
{
_lock.EnterReadLock();
返回_hashSet.Contains(项目);
}
最后
{
如果(_lock.IsReadLockHeld)_lock.ExitReadLock();
}
}
公共BOOL删除(T项目)
{
尝试
{
_lock.EnterWriteLock();
返回_hashSet.Remove(项目);
}
最后
{
如果(_lock.IsWriteLockHeld)_lock.ExitWriteLock();
}
}
公众诠释计数
{
得到
{
尝试
{
_lock.EnterReadLock();
返回_hashSet.Count;
}
最后
{
如果(_lock.IsReadLockHeld)_lock.ExitReadLock();
}
}
}
#endregion
#地区处置
公共无效的Dispose()
{
如果(_lock!= NULL)_lock.Dispose();
}
#endregion
}
}
还没有真正测试过(性能 - 或可靠性明智)。情况因人而异。
I am trying to implement a ConcurrentHashSet in the spirit of ConcurrentDictionary,approach taken is to use a internal backing ConcurrentDictionary and write small delegating methods, this is how far i got, but well the set theoretic methods are I am stuck on, esp. I am not sure if I can use a foreach and still not violate concurrency
public class ConcurrentHashSet<TElement> : ISet<TElement>
{
private readonly ConcurrentDictionary<TElement, object> _internal;
public ConcurrentHashSet(IEnumerable<TElement> elements = null)
{
_internal = new ConcurrentDictionary<TElement, object>();
if (elements != null)
UnionWith(elements);
}
public void UnionWith(IEnumerable<TElement> other)
{
if (other == null) throw new ArgumentNullException("other");
foreach (var otherElement in other)
Add(otherElement);
}
public void IntersectWith(IEnumerable<TElement> other)
{
throw new NotImplementedException();
}
public void ExceptWith(IEnumerable<TElement> other)
{
throw new NotImplementedException();
}
public void SymmetricExceptWith(IEnumerable<TElement> other)
{
throw new NotImplementedException();
}
public bool IsSubsetOf(IEnumerable<TElement> other)
{
throw new NotImplementedException();
}
public bool IsSupersetOf(IEnumerable<TElement> other)
{
throw new NotImplementedException();
}
public bool IsProperSupersetOf(IEnumerable<TElement> other)
{
throw new NotImplementedException();
}
public bool IsProperSubsetOf(IEnumerable<TElement> other)
{
throw new NotImplementedException();
}
public bool Overlaps(IEnumerable<TElement> other)
{
return other.Any(otherElement => _internal.ContainsKey(otherElement));
}
public bool SetEquals(IEnumerable<TElement> other)
{
int otherCount = 0;
int thisCount = Count;
foreach (var otherElement in other)
{
otherCount++;
if (!_internal.ContainsKey(otherElement))
return false;
}
return otherCount == thisCount;
}
public bool Add(TElement item)
{
return _internal.TryAdd(item, null);
}
public void Clear()
{
_internal.Clear();
}
// I am not sure here if that fullfills contract correctly
void ICollection<TElement>.Add(TElement item)
{
Add(item);
}
public bool Contains(TElement item)
{
return _internal.ContainsKey(item);
}
public void CopyTo(TElement[] array, int arrayIndex)
{
_internal.Keys.CopyTo(array, arrayIndex);
}
public bool Remove(TElement item)
{
object ignore;
return _internal.TryRemove(item, out ignore);
}
public int Count
{
get { return _internal.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public IEnumerator<TElement> GetEnumerator()
{
return _internal.Keys.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
I just ran into a similar scenario ("I am interested in a fast Add and Contains and Remove") and implemented this sucker:
using System.Collections.Generic;
using System.Threading;
namespace BlahBlah.Utilities
{
public class ConcurrentHashSet<T> : IDisposable
{
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private readonly HashSet<T> _hashSet = new HashSet<T>();
#region Implementation of ICollection<T> ...ish
public bool Add(T item)
{
try
{
_lock.EnterWriteLock();
return _hashSet.Add(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
public void Clear()
{
try
{
_lock.EnterWriteLock();
_hashSet.Clear();
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
public bool Contains(T item)
{
try
{
_lock.EnterReadLock();
return _hashSet.Contains(item);
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
public bool Remove(T item)
{
try
{
_lock.EnterWriteLock();
return _hashSet.Remove(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
public int Count
{
get
{
try
{
_lock.EnterReadLock();
return _hashSet.Count;
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
}
#endregion
#region Dispose
public void Dispose()
{
if (_lock != null) _lock.Dispose();
}
#endregion
}
}
Haven't really tested it (performance- or reliability-wise). YMMV.
这篇关于如何在.net实施ConcurrentHashSet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!