ConcurrentList.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. namespace MeloongCore;
  2. /// <summary>
  3. /// 使用粗粒度锁的线程安全 <see cref="List{T}"/> 实现。
  4. /// 通常建议使用 <see cref="ConcurrentBag{T}"/> 或其他线程安全集合,它们具有更好的性能。
  5. /// </summary>
  6. public class ConcurrentList<T> : IList<T>, IList {
  7. private readonly List<T> _items = [];
  8. // 构造函数
  9. public ConcurrentList() { }
  10. public ConcurrentList(IEnumerable<T> data) => _items = new(data);
  11. public static implicit operator ConcurrentList<T>(List<T> data) => new(data);
  12. public static implicit operator List<T>(ConcurrentList<T> data) { lock (data.SyncRoot) { return new(data._items); } }
  13. // 枚举器
  14. /// <summary>
  15. /// 返回此列表的副本。
  16. /// </summary>
  17. public IEnumerator<T> GetEnumerator() { lock (SyncRoot) return _items.ToList().GetEnumerator(); }
  18. /// <summary>
  19. /// 返回此列表的副本。
  20. /// </summary>
  21. IEnumerator IEnumerable.GetEnumerator() { lock (SyncRoot) return _items.ToList().GetEnumerator(); }
  22. // 成员
  23. public int Count { get { lock (SyncRoot) { return _items.Count; } } }
  24. public bool IsReadOnly => false;
  25. bool IList.IsFixedSize => false;
  26. bool ICollection.IsSynchronized => true;
  27. public readonly object SyncRoot = new();
  28. object ICollection.SyncRoot => SyncRoot;
  29. public T this[int index] {
  30. get { lock (SyncRoot) { return _items[index]; } }
  31. set { lock (SyncRoot) { _items[index] = value; } }
  32. }
  33. object? IList.this[int index] {
  34. get => this[index];
  35. set { lock (SyncRoot) { _items[index] = (T) value!; } }
  36. }
  37. public void Add(T item) { lock (SyncRoot) { _items.Add(item); } }
  38. int IList.Add(object? value) { lock (SyncRoot) { _items.Add((T) value!); return _items.Count - 1; } }
  39. public void Insert(int index, T item) { lock (SyncRoot) { _items.Insert(index, item); } }
  40. void IList.Insert(int index, object? value) { lock (SyncRoot) { _items.Insert(index, (T) value!); } }
  41. public bool Remove(T item) { lock (SyncRoot) { return _items.Remove(item); } }
  42. void IList.Remove(object? value) { lock (SyncRoot) { if (value is T t) _items.Remove(t); } }
  43. public void RemoveAt(int index) { lock (SyncRoot) { _items.RemoveAt(index); } }
  44. public void Clear() { lock (SyncRoot) { _items.Clear(); } }
  45. public bool Contains(T item) { lock (SyncRoot) { return _items.Contains(item); } }
  46. bool IList.Contains(object? value) { lock (SyncRoot) { return value is T t && _items.Contains(t); } }
  47. public int IndexOf(T item) { lock (SyncRoot) { return _items.IndexOf(item); } }
  48. int IList.IndexOf(object? value) { lock (SyncRoot) { return value is T t ? _items.IndexOf(t) : -1; } }
  49. public void CopyTo(T[] array, int arrayIndex) { lock (SyncRoot) { _items.CopyTo(array, arrayIndex); } }
  50. void ICollection.CopyTo(Array array, int index) { lock (SyncRoot) { ((ICollection) _items).CopyTo(array, index); } }
  51. }