C# 中实现安全集合Concurrent 支持删除指定元素的

news/2024/10/21 19:49:04/

ConcurrentBag实现了IProducerConsumerCollection接口,该接口主要用于生产者消费者模式下,可见该类基本就是为生产消费者模式定制的。然后还实现了常规的IReadOnlyCollection类,实现了该类就需要实现IEnumerable、IEnumerable、 ICollection类。

ConcurrentBag对外提供的方法没有List那么多,但是同样有Enumerable实现的扩展方法。类本身提供的方法如下所示。

名称 说明
Add 将对象添加到 ConcurrentBag 中。
CopyTo 从指定数组索引开始,将 ConcurrentBag 元素复制到现有的一维 Array 中。
Equals(Object) 确定指定的 Object 是否等于当前的 Object。 (继承自 Object。)
Finalize 允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作。 (继承自 Object。)
GetEnumerator 返回循环访问 ConcurrentBag 的枚举器。
GetHashCode 用作特定类型的哈希函数。 (继承自 Object。)
GetType 获取当前实例的 Type。 (继承自 Object。)
MemberwiseClone 创建当前 Object 的浅表副本。 (继承自 Object。)
ToArray 将 ConcurrentBag 元素复制到新数组。
ToString 返回表示当前对象的字符串。 (继承自 Object。)
TryPeek 尝试从 ConcurrentBag 返回一个对象但不移除该对象。
TryTake 尝试从 ConcurrentBag 中移除并返回对象。

该官网提供集合,不支持删除指定对象,因此自己 使用list 和lock 实现线程安全 集合类型

using System.Collections;namespace TestLib;public class ConcurrentList<T> : IList<T>
{private readonly IList<T> _list = new List<T>();private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);public ConcurrentList(){}public ConcurrentList(List<T> values){_list = values;}private void ConcurrentAction(Action<IList<T>> action){ConcurrentAction(x => x.EnterWriteLock(), x => x.ExitWriteLock(), action);}private void ConcurrentAction(Action<ReaderWriterLockSlim> enter, Action<ReaderWriterLockSlim> exit, Action<IList<T>> action){try{enter(_lock);action(_list);}finally{exit(_lock);}}private TResult ConcurrentFunc<TResult>(Func<IList<T>, TResult> func)=> ConcurrentFunc(x => x.EnterReadLock(), x => x.ExitReadLock(), func);private TResult ConcurrentFunc<TResult>(Action<ReaderWriterLockSlim> enter, Action<ReaderWriterLockSlim> exit, Func<IList<T>, TResult> func){try{enter(_lock);return func(_list);}finally{exit(_lock);}}public void AddRange(IEnumerable<T> values){ConcurrentAction(l =>{foreach (var value in values){l.Add(value);}});}public void Add(T item) => ConcurrentAction(l => l.Add(item));public bool Remove(T item) => ConcurrentFunc(l => l.Remove(item));public void Clear() => ConcurrentAction(l => l.Clear());public bool Contains(T item) => ConcurrentFunc(l => l.Contains(item));public void CopyTo(T[] array, int arrayIndex) => ConcurrentAction(l => l.CopyTo(array, arrayIndex));public int Count => ConcurrentFunc(l => l.Count);public bool IsReadOnly => ConcurrentFunc(l => l.IsReadOnly);public int IndexOf(T item) => ConcurrentFunc(l => l.IndexOf(item));public void Insert(int index, T item) => ConcurrentAction(l => l.Insert(index, item));public void RemoveAt(int index) => ConcurrentAction(l => l.RemoveAt(index));public T this[int index]{get => ConcurrentFunc(l => l[index]);set => ConcurrentAction(l => l[index] = value);}IEnumerator<T> IEnumerable<T>.GetEnumerator(){return new ConcurrentEnumerator<T>(_list, _lock);}System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){return new ConcurrentEnumerator<T>(_list, _lock);}
}class ConcurrentEnumerator<T> : System.Collections.Generic.IEnumerator<T>
{private readonly ReaderWriterLockSlim _lock;private readonly IEnumerator<T> _enumerator;internal ConcurrentEnumerator(IEnumerable<T> target, ReaderWriterLockSlim lockSlim){_lock = lockSlim;_lock.EnterReadLock();_enumerator = target.GetEnumerator();}public T Current => _enumerator.Current;public bool MoveNext(){return _enumerator.MoveNext();}public void Reset(){_enumerator.Reset();}public void Dispose(){_lock.ExitReadLock();}object IEnumerator.Current => Current;
}

http://www.ppmy.cn/news/1540881.html

相关文章

神经网络反向传播交叉熵 计算损失函数对隐藏层激活值a1的梯度

本文是交叉熵损失函数为代表的两层神经网络的反向传播量化求导计算公式中的一个公式&#xff0c;单独拿出来做一下解释说明。 公式 8-16 是反向传播算法中&#xff0c;用于计算损失函数对隐藏层激活值 a 1 a_1 a1​ 的梯度。在反向传播过程中&#xff0c;损失函数对隐藏层激活…

基于MinIO配置bucket,用于文件下载和浏览

文章目录 引言I 配置文件浏览安装MinIO配置自启动服务访问权限配置文件浏览访问地址文件下载地址II 知识扩展MinIO内置访问策略只读策略只写策略读写策略diagnosticsconsoleAdmin引言 需求:文件下载用于OTA升级,文件浏览用于产品展示。 实现方案:基于MinIO配置bucket访问权…

Android Automotive 获得谷歌地图事故报告功能

Android Automotive 迎来了谷歌地图的实时事故报告功能&#xff0c;这一更新标志着它与 Android Auto 的功能差距进一步缩小。 Android Auto 主要是通过手机与汽车的连接来提供服务&#xff0c;而Android Automotive 则是为汽车量身定制的系统——这在软件更新和用户体验上带来…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第十四集:制作新的场景以及制作创建切换管理系统

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、制作新的场景 1.重新翻新各种Sprite2.制作地图前期应该做的事情3.疯狂的制作地图二、制作场景切换管理系统 1.制作场景切换点TransitionPoint2.切换场景时的…

Android Framework AMS(08)service组件分析-2(startService和StopService关键流程分析)

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;上一章节主要解读应用层service组件启动的2种方式startService和bindService&#xff0c;以及从APP层到AMS调用之间的打通。本章节主要关注service…

深入解析缓存与数据库数据不一致问题

缓存层是提高系统响应速度和扩展性的关键组件。然而&#xff0c;缓存层的引入也带来了数据一致性的挑战。 当数据库中的数据发生变化时&#xff0c;如何确保这些变化能够及时且准确地反映到缓存中&#xff0c;是确保用户体验和系统可靠性的重要问题。 1. 数据一致性 首先&am…

go压缩的使用

基础&#xff1a;使用go创建一个zip func base(path string) {// 创建 zip 文件zipFile, err : os.Create("test.zip")if err ! nil {panic(err)}defer zipFile.Close()// 创建一个新的 *Writer 对象zipWriter : zip.NewWriter(zipFile)defer zipWriter.Close()// 创…

原理代码解读:基于DiT结构视频生成模型的ControlNet

Diffusion Models视频生成-博客汇总 前言:相比于基于UNet结构的视频生成模型,DiT结构的模型最大的劣势在于生态不够完善,配套的ControlNet、IP-Adapter等开源权重不多,导致难以落地。最近DiT-based 5B的ControlNet开源了,相比于传统的ControlNet有不少改进点,这篇博客将从…