如何从ConcurrentBag中删除所有项目?

如何清除ConcurrentBag ? 它没有任何方法像ClearRemoveAll

 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,但是也允许你快速检查一个键是否存在。 “快速”当然是一个相对术语,但根据您的使用情况,它可能比列举大堆栈更快。