如何从ConcurrentBag中删除所有项目?
如何清除ConcurrentBag
? 它没有任何方法像Clear
或RemoveAll
…
T someItem; while (!myBag.IsEmpty) { myBag.TryTake(out someItem); }
更新10/03/2017:正如@Lou正确指出,分配是primefaces。 在这种情况下, ConcurrentBag
创build不会是primefaces的,但是将该引用放到variables中将是primefaces的 – 所以locking或Interlocked.Exchange
围绕它的Interlocked.Exchange
不是严格要求的。
进一步阅读:
引用赋值是primefaces,所以为什么Interlocked.Exchange(ref Object,Object)需要?
是一个引用分配线程安全吗?
您始终可以locking对包本身的访问权限并创build一个新的实例。 如果没有别的东西在他们的手中,袋子里的东西就可以用于GC了:
lock (something) { bag = new ConcurrentBag(); }
或者像Lukazoid指出的那样:
var newBag = new ConcurrentBag(); Interlocked.Exchange<ConcurrentBag>(ref bag, newBag);
简单的方法来收集内容,但是,这假定每当一个项目想要访问它也获得locking – 这可能是昂贵的,可能会取消进入ConcurrentBag
本身的性能调整。
如果你知道这个时候没有别的东西可以进入这个袋子,那么请你永远祈祷,不要locking:-)
所选的答案是一种解决方法,所以我添加了我自己的解决方法。
我的解决scheme是查看System.Collections.Concurrent命名空间中的所有可用集合,以find一个清除集合中所有元素的细节。
ConcurrentStack类有一个Clear()方法,它从集合中删除所有的元素。 实际上,它是名称空间(当前)唯一的集合。 是的,你必须Push(T element)
而不是Add(T element)
,但坦率地说,这是值得的时间保存。
您可以在循环中逐个删除对象:
object result; while (bag.TryTake(out result));
请注意,此循环之后bag不保证为空,因为项目可以在循环完成后添加,并且在下一个语句之前由不同的线程添加。
本着变通的方法.. ConcurrentDictionary<T, bool>
有一个primefacesClear,但是也允许你快速检查一个键是否存在。 “快速”当然是一个相对术语,但根据您的使用情况,它可能比列举大堆栈更快。