ConcurrentBag将允许多个线程添加和删除包中的项目。线程可能会将一个项目添加到包中,然后最终将该项目重新取出。它说ConcurrentBag是无序的,但是它有多无序?在单个线程上,行李就像一个堆栈。无序意味着“不像链表”?
ConcurrentBag的实际使用是什么?
答案 0 :(得分:16)
因为没有排序,ConcurrentBag比ConcurrentStack / Queue具有性能优势。它由Microsoft实现为本地线程存储。因此,添加项目的每个线程都会在自己的空间中执行此操作。检索项目时,它们来自本地存储。只有当它为空时,线程才会从另一个线程存储中窃取项目。因此,ConcurrentBag不是一个简单的列表,而是一个分布式的项目列表。并且几乎是无锁的,并且应该在高并发性的情况下更好地扩展。
不幸的是,在.NET 4.0中存在性能问题(在4.5中修复) http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0
答案 1 :(得分:2)
包对于跟踪实例计数非常有用。例如,如果要记录您为Web请求提供服务的主机,可以在开始为请求提供服务时将其IP添加到包中,并在完成后将其删除。
使用行李可以让您快速了解您目前正在服务的IP。它还可以让您快速查询是否在为给定的IP地址提供服务。
如果您使用的是一个集合而不是一个包,那么来自同一IP地址的多个并发请求将会破坏您的记录保存。
答案 2 :(得分:1)
您只需跟踪其中的内容,不需要随机访问或保证订单。如果你有一个线程可以添加要处理的项目,并且有一个线程可以删除项目以便处理它们,那么如果你不关心它们是按FIFO顺序处理的,那么并发包就可以正常工作。
答案 3 :(得分:1)
感谢@Chris Jester-Young我提出了一个很好的,真实世界的场景,实际上适用于我正在进行的项目。
查找 - 处理 - 存储
查找 - 主题1& 2设置为查找或刮取数据(文件系统,Web等)。这些结果存储在ConcurrentBag1中。
流程 - 主题3& 4设置为取出ConcurrentBag1,清理/转换/处理数据,然后将结果存储在ConcurrentBag2中。
存储 - 设置线程5以从ConcurrentBag2收集结果并将结果存储在SQL中。