| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.Serialization;
- using System.Threading;
- namespace Masuit.Tools.Systems;
- /// <summary>
- /// 并发HashSet
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public sealed class ConcurrentHashSet<T> : ISet<T>, IDisposable
- {
- private readonly ReaderWriterLockSlim _lock = new(LockRecursionPolicy.SupportsRecursion);
- private readonly HashSet<T> _hashSet = new();
- public int Count
- {
- get
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.Count;
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- }
- public bool IsReadOnly => false;
- public ConcurrentHashSet()
- {
- }
- public ConcurrentHashSet(IEqualityComparer<T> comparer)
- {
- _hashSet = new HashSet<T>(comparer);
- }
- public ConcurrentHashSet(IEnumerable<T> collection)
- {
- _hashSet = new HashSet<T>(collection);
- }
- public ConcurrentHashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer)
- {
- _hashSet = new HashSet<T>(collection, comparer);
- }
- public ConcurrentHashSet(SerializationInfo info, StreamingContext context)
- {
- _hashSet = new HashSet<T>();
- var iSerializable = (ISerializable)_hashSet;
- iSerializable.GetObjectData(info, context);
- }
- public void OnDeserialization(object sender)
- {
- _hashSet.OnDeserialization(sender);
- }
- public void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- _hashSet.GetObjectData(info, context);
- }
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- public IEnumerator<T> GetEnumerator()
- {
- return _hashSet.GetEnumerator();
- }
- public void Add(T item)
- {
- _lock.EnterWriteLock();
- try
- {
- _hashSet.Add(item);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public bool TryAdd(T item)
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.Add(item);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public void UnionWith(IEnumerable<T> other)
- {
- _lock.EnterWriteLock();
- _lock.EnterReadLock();
- try
- {
- _hashSet.UnionWith(other);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- if (_lock.IsReadLockHeld)
- {
- _lock.ExitReadLock();
- }
- }
- }
- public void IntersectWith(IEnumerable<T> other)
- {
- _lock.EnterWriteLock();
- _lock.EnterReadLock();
- try
- {
- _hashSet.IntersectWith(other);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- if (_lock.IsReadLockHeld)
- {
- _lock.ExitReadLock();
- }
- }
- }
- public void ExceptWith(IEnumerable<T> other)
- {
- _lock.EnterWriteLock();
- _lock.EnterReadLock();
- try
- {
- _hashSet.ExceptWith(other);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- if (_lock.IsReadLockHeld)
- {
- _lock.ExitReadLock();
- }
- }
- }
- public void SymmetricExceptWith(IEnumerable<T> other)
- {
- _lock.EnterWriteLock();
- try
- {
- _hashSet.SymmetricExceptWith(other);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public bool IsSubsetOf(IEnumerable<T> other)
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.IsSubsetOf(other);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public bool IsSupersetOf(IEnumerable<T> other)
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.IsSupersetOf(other);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public bool IsProperSupersetOf(IEnumerable<T> other)
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.IsProperSupersetOf(other);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public bool IsProperSubsetOf(IEnumerable<T> other)
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.IsProperSubsetOf(other);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public bool Overlaps(IEnumerable<T> other)
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.Overlaps(other);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public bool SetEquals(IEnumerable<T> other)
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.SetEquals(other);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- bool ISet<T>.Add(T item)
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.Add(item);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public void Clear()
- {
- _lock.EnterWriteLock();
- try
- {
- _hashSet.Clear();
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public bool Contains(T item)
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.Contains(item);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public void CopyTo(T[] array, int arrayIndex)
- {
- _lock.EnterWriteLock();
- try
- {
- _hashSet.CopyTo(array, arrayIndex);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public bool Remove(T item)
- {
- _lock.EnterWriteLock();
- try
- {
- return _hashSet.Remove(item);
- }
- finally
- {
- if (_lock.IsWriteLockHeld)
- {
- _lock.ExitWriteLock();
- }
- }
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- private void Dispose(bool disposing)
- {
- if (disposing && _lock != null)
- {
- _lock.Dispose();
- }
- }
- ~ConcurrentHashSet()
- {
- Dispose(false);
- }
- }
|