diff --git a/ArchiSteamFarm/ArchiSteamFarm.csproj b/ArchiSteamFarm/ArchiSteamFarm.csproj index 6ae56e07b..ecc48e962 100644 --- a/ArchiSteamFarm/ArchiSteamFarm.csproj +++ b/ArchiSteamFarm/ArchiSteamFarm.csproj @@ -60,7 +60,6 @@ - diff --git a/ArchiSteamFarm/Collections/ConcurrentEnumerator.cs b/ArchiSteamFarm/Collections/ConcurrentEnumerator.cs index 04e489291..8a4bbc06d 100644 --- a/ArchiSteamFarm/Collections/ConcurrentEnumerator.cs +++ b/ArchiSteamFarm/Collections/ConcurrentEnumerator.cs @@ -22,6 +22,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Threading; using JetBrains.Annotations; namespace ArchiSteamFarm.Collections { @@ -29,22 +30,24 @@ namespace ArchiSteamFarm.Collections { public T Current => Enumerator.Current; private readonly IEnumerator Enumerator; - private readonly IDisposable Lock; + private readonly ReaderWriterLockSlim Lock; object IEnumerator.Current => Current; - internal ConcurrentEnumerator([NotNull] IReadOnlyCollection collection, [NotNull] IDisposable @lock) { + internal ConcurrentEnumerator([NotNull] IReadOnlyCollection collection, [NotNull] ReaderWriterLockSlim @lock) { if ((collection == null) || (@lock == null)) { throw new ArgumentNullException(nameof(collection) + " || " + nameof(@lock)); } + @lock.EnterReadLock(); + Lock = @lock; Enumerator = collection.GetEnumerator(); } public void Dispose() { Enumerator.Dispose(); - Lock.Dispose(); + Lock.ExitReadLock(); } public bool MoveNext() => Enumerator.MoveNext(); diff --git a/ArchiSteamFarm/Collections/ConcurrentList.cs b/ArchiSteamFarm/Collections/ConcurrentList.cs index ac2878955..2303c97ed 100644 --- a/ArchiSteamFarm/Collections/ConcurrentList.cs +++ b/ArchiSteamFarm/Collections/ConcurrentList.cs @@ -22,7 +22,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using Nito.AsyncEx; +using System.Threading; namespace ArchiSteamFarm.Collections { internal sealed class ConcurrentList : IList, IReadOnlyList { @@ -30,81 +30,125 @@ namespace ArchiSteamFarm.Collections { internal int Count { get { - using (Lock.ReaderLock()) { + Lock.EnterReadLock(); + + try { return BackingCollection.Count; + } finally { + Lock.ExitReadLock(); } } } private readonly List BackingCollection = new List(); - private readonly AsyncReaderWriterLock Lock = new AsyncReaderWriterLock(); + private readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim(); int ICollection.Count => Count; int IReadOnlyCollection.Count => Count; public T this[int index] { get { - using (Lock.ReaderLock()) { + Lock.EnterReadLock(); + + try { return BackingCollection[index]; + } finally { + Lock.ExitReadLock(); } } set { - using (Lock.WriterLock()) { + Lock.EnterWriteLock(); + + try { BackingCollection[index] = value; + } finally { + Lock.ExitWriteLock(); } } } public void Add(T item) { - using (Lock.WriterLock()) { + Lock.EnterWriteLock(); + + try { BackingCollection.Add(item); + } finally { + Lock.ExitWriteLock(); } } public void Clear() { - using (Lock.WriterLock()) { + Lock.EnterWriteLock(); + + try { BackingCollection.Clear(); + } finally { + Lock.ExitWriteLock(); } } public bool Contains(T item) { - using (Lock.ReaderLock()) { + Lock.EnterReadLock(); + + try { return BackingCollection.Contains(item); + } finally { + Lock.ExitReadLock(); } } public void CopyTo(T[] array, int arrayIndex) { - using (Lock.ReaderLock()) { + Lock.EnterReadLock(); + + try { BackingCollection.CopyTo(array, arrayIndex); + } finally { + Lock.ExitReadLock(); } } [JetBrains.Annotations.NotNull] [SuppressMessage("ReSharper", "AnnotationRedundancyInHierarchy")] - public IEnumerator GetEnumerator() => new ConcurrentEnumerator(BackingCollection, Lock.ReaderLock()); + public IEnumerator GetEnumerator() => new ConcurrentEnumerator(BackingCollection, Lock); public int IndexOf(T item) { - using (Lock.ReaderLock()) { + Lock.EnterReadLock(); + + try { return BackingCollection.IndexOf(item); + } finally { + Lock.ExitReadLock(); } } public void Insert(int index, T item) { - using (Lock.WriterLock()) { + Lock.EnterWriteLock(); + + try { BackingCollection.Insert(index, item); + } finally { + Lock.ExitWriteLock(); } } public bool Remove(T item) { - using (Lock.WriterLock()) { + Lock.EnterWriteLock(); + + try { return BackingCollection.Remove(item); + } finally { + Lock.ExitWriteLock(); } } public void RemoveAt(int index) { - using (Lock.WriterLock()) { + Lock.EnterWriteLock(); + + try { BackingCollection.RemoveAt(index); + } finally { + Lock.ExitWriteLock(); } } @@ -113,9 +157,13 @@ namespace ArchiSteamFarm.Collections { IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); internal void ReplaceWith([JetBrains.Annotations.NotNull] IEnumerable collection) { - using (Lock.WriterLock()) { + Lock.EnterWriteLock(); + + try { BackingCollection.Clear(); BackingCollection.AddRange(collection); + } finally { + Lock.ExitWriteLock(); } } }