ConcurrentList.cs 2.8 KB

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