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. public readonly object syncLock = new();
  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.syncLock) { return new(data._items); } }
  13. // 枚举器
  14. /// <summary>
  15. /// 返回此列表的副本。
  16. /// </summary>
  17. public IEnumerator<T> GetEnumerator() { lock (syncLock) return _items.ToList().GetEnumerator(); }
  18. /// <summary>
  19. /// 返回此列表的副本。
  20. /// </summary>
  21. IEnumerator IEnumerable.GetEnumerator() { lock (syncLock) return _items.ToList().GetEnumerator(); }
  22. // 成员
  23. public int Count { get { lock (syncLock) { return _items.Count; } } }
  24. public bool IsReadOnly => false;
  25. bool IList.IsFixedSize => false;
  26. bool ICollection.IsSynchronized => true;
  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. }