diff --git a/src/ShardingCore/Core/Collections/SafeReadAppendList.cs b/src/ShardingCore/Core/Collections/SafeReadAppendList.cs index 0cf889b0..eccb525e 100644 --- a/src/ShardingCore/Core/Collections/SafeReadAppendList.cs +++ b/src/ShardingCore/Core/Collections/SafeReadAppendList.cs @@ -1,22 +1,44 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using System.Threading; namespace ShardingCore.Core.Collections { - - public class SafeReadAppendList + public sealed class SafeReadAppendList { private ImmutableList _list; + private readonly object COPY_LOCK = new object(); + public SafeReadAppendList(IEnumerable list) { _list = ImmutableList.CreateRange(list); } - public SafeReadAppendList():this(new List(0)) + + public SafeReadAppendList() : this(new List(0)) { } - public ImmutableList Data => _list; + public List CopyList + { + get + { + if (_copyList?.Count != _list.Count) + { + lock (COPY_LOCK) + { + if (_copyList?.Count != _list.Count) + { + _copyList = _list.ToList(); + } + } + } + + return _copyList; + } + } + + public List _copyList; public void Append(T value) { @@ -26,9 +48,12 @@ namespace ShardingCore.Core.Collections { original = _list!; afterChange = _list!.Add(value); - } - while (Interlocked.CompareExchange(ref _list, afterChange, original) != original); + } while (Interlocked.CompareExchange(ref _list, afterChange, original) != original); } + public bool Contains(T value) + { + return _list.Contains(value); + } } -} +} \ No newline at end of file diff --git a/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingAutoCreateOperatorVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingAutoCreateOperatorVirtualTableRoute.cs index f52170c1..69cc9be3 100644 --- a/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingAutoCreateOperatorVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingAutoCreateOperatorVirtualTableRoute.cs @@ -39,7 +39,8 @@ namespace ShardingCore.VirtualRoutes.Abstractions public override List GetTails() { - return _tails.Data.ToList(); + // ReSharper disable once InconsistentlySynchronizedField + return _tails.CopyList; } protected abstract List CalcTailsOnStart(); @@ -48,7 +49,7 @@ namespace ShardingCore.VirtualRoutes.Abstractions { lock (APPEND_LOCK) { - if (!_tails.Data.Contains(tail)) + if (!_tails.Contains(tail)) { _tails.Append(tail); return true;