ConcurrentList.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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. private readonly object _lock = 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._lock) { return new List<T>(data._items); } }
  14. public int Count { get { lock (_lock) { return _items.Count; } } }
  15. public bool IsReadOnly => false;
  16. bool IList.IsFixedSize => false;
  17. bool ICollection.IsSynchronized => true;
  18. object ICollection.SyncRoot => _lock;
  19. public T this[int index] {
  20. get { lock (_lock) { return _items[index]; } }
  21. set { lock (_lock) { _items[index] = value; } }
  22. }
  23. object? IList.this[int index] {
  24. get => this[index];
  25. set { lock (_lock) { _items[index] = (T)value!; } }
  26. }
  27. public void Add(T item) { lock (_lock) { _items.Add(item); } }
  28. int IList.Add(object? value) { lock (_lock) { _items.Add((T)value!); return _items.Count - 1; } }
  29. public void Insert(int index, T item) { lock (_lock) { _items.Insert(index, item); } }
  30. void IList.Insert(int index, object? value) { lock (_lock) { _items.Insert(index, (T)value!); } }
  31. public bool Remove(T item) { lock (_lock) { return _items.Remove(item); } }
  32. void IList.Remove(object? value) { lock (_lock) { if (value is T t) _items.Remove(t); } }
  33. public void RemoveAt(int index) { lock (_lock) { _items.RemoveAt(index); } }
  34. public void Clear() { lock (_lock) { _items.Clear(); } }
  35. public bool Contains(T item) { lock (_lock) { return _items.Contains(item); } }
  36. bool IList.Contains(object? value) { lock (_lock) { return value is T t && _items.Contains(t); } }
  37. public int IndexOf(T item) { lock (_lock) { return _items.IndexOf(item); } }
  38. int IList.IndexOf(object? value) { lock (_lock) { return value is T t ? _items.IndexOf(t) : -1; } }
  39. public void CopyTo(T[] array, int arrayIndex) { lock (_lock) { _items.CopyTo(array, arrayIndex); } }
  40. void ICollection.CopyTo(Array array, int index) { lock (_lock) { ((ICollection)_items).CopyTo(array, index); } }
  41. // 对枚举器进行覆写,返回一个临时副本
  42. public IEnumerator<T> GetEnumerator() {
  43. lock (_lock) {
  44. return _items.ToList().GetEnumerator();
  45. }
  46. }
  47. IEnumerator IEnumerable.GetEnumerator() {
  48. lock (_lock) {
  49. return _items.ToList().GetEnumerator();
  50. }
  51. }
  52. }