|
|
@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace Connected.Collections.Concurrent;
|
|
|
|
|
|
|
|
public class ConcurrentList<T> : IList<T>, IEnumerable<T>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
private readonly List<T> _values = new();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public T this[int index]
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
get
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return _values[index];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
set
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_values[index] = value;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public int Count
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
get
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return _values.Count;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsReadOnly => false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Add(T item)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_values.Add(item);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_values.Clear();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public bool Contains(T item)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return _values.Contains(item);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void CopyTo(T[] array, int arrayIndex)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
foreach (var value in _values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (array.Length >= arrayIndex)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
array.SetValue(value, arrayIndex++);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
array.Append(value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public IEnumerator<T> GetEnumerator()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return _values.ToImmutableList(false).GetEnumerator();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public int IndexOf(T item)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return _values.IndexOf(item);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Insert(int index, T item)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_values.Insert(index, item);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public bool Remove(T item)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return _values.Remove(item);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void RemoveAt(int index)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_values.RemoveAt(index);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock (_values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return _values.ToImmutableList(false).GetEnumerator();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|