ConcurrentList.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. namespace MeloongCore;
  2. /// <summary>
  3. /// 线程安全的 <see cref="List{T}"/> 实现。
  4. /// 当调用枚举器时返回一个临时副本,以避免列表在枚举过程中被修改导致异常。
  5. /// </summary>
  6. public class ConcurrentList<T> : IList<T>, IList, IEnumerable, IEnumerable<T> {
  7. private readonly List<T> _items = [];
  8. public readonly object syncLock = new();
  9. // 构造函数
  10. public ConcurrentList() { }
  11. public ConcurrentList(IEnumerable<T> data) => _items = new List<T>(data);
  12. public static implicit operator ConcurrentList<T>(List<T> data) => new(data);
  13. public static implicit operator List<T>(ConcurrentList<T> data) { lock (data.syncLock) { return new List<T>(data._items); } }
  14. // 枚举器
  15. public IEnumerator<T> GetEnumerator() {
  16. lock (syncLock) {
  17. return _items.ToList().GetEnumerator();
  18. }
  19. }
  20. IEnumerator IEnumerable.GetEnumerator() {
  21. lock (syncLock) {
  22. return _items.ToList().GetEnumerator();
  23. }
  24. }
  25. // 成员
  26. public int Count { get { lock (syncLock) { return _items.Count; } } }
  27. public bool IsReadOnly => false;
  28. bool IList.IsFixedSize => false;
  29. bool ICollection.IsSynchronized => true;
  30. object ICollection.SyncRoot => syncLock;
  31. public T this[int index] {
  32. get { lock (syncLock) { return _items[index]; } }
  33. set { lock (syncLock) { _items[index] = value; } }
  34. }
  35. object? IList.this[int index] {
  36. get => this[index];
  37. set { lock (syncLock) { _items[index] = (T) value!; } }
  38. }
  39. public void Add(T item) { lock (syncLock) { _items.Add(item); } }
  40. int IList.Add(object? value) { lock (syncLock) { _items.Add((T) value!); return _items.Count - 1; } }
  41. public void Insert(int index, T item) { lock (syncLock) { _items.Insert(index, item); } }
  42. void IList.Insert(int index, object? value) { lock (syncLock) { _items.Insert(index, (T) value!); } }
  43. public bool Remove(T item) { lock (syncLock) { return _items.Remove(item); } }
  44. void IList.Remove(object? value) { lock (syncLock) { if (value is T t) _items.Remove(t); } }
  45. public void RemoveAt(int index) { lock (syncLock) { _items.RemoveAt(index); } }
  46. public void Clear() { lock (syncLock) { _items.Clear(); } }
  47. public bool Contains(T item) { lock (syncLock) { return _items.Contains(item); } }
  48. bool IList.Contains(object? value) { lock (syncLock) { return value is T t && _items.Contains(t); } }
  49. public int IndexOf(T item) { lock (syncLock) { return _items.IndexOf(item); } }
  50. int IList.IndexOf(object? value) { lock (syncLock) { return value is T t ? _items.IndexOf(t) : -1; } }
  51. public void CopyTo(T[] array, int arrayIndex) { lock (syncLock) { _items.CopyTo(array, arrayIndex); } }
  52. void ICollection.CopyTo(Array array, int index) { lock (syncLock) { ((ICollection) _items).CopyTo(array, index); } }
  53. }