【发布时间】:2022-01-13 22:05:18
【问题描述】:
我有一个 ConcurrentBag 对象,我想对其进行以下操作:
- 使用 where 过滤枚举所有项目。
- 为每个项目检查一些属性,并根据值进行一些方法调用。方法调用后,最好从包中取出物品。
- 修改一些属性的值并保存到包中。
所以基本上我需要以下内容:
foreach (var item in myBag.Where(it => it.Property1 = true))
{
if (item.Property2 = true)
{
SomeMethodToReadTheItem(item);
//it's better to remove this item from the bag here, but
//there is a permeance hit, then just leave it.
}
else
{
item.Property3= "new value";
//now how do I save the item back to the bag?
}
}
因为它应该以线程安全的方式完成。我知道对 ConcurrentBag 的枚举实际上是对真实包的“快照”,但是使用 where 子句过滤器怎么样?我应该做一个 ToList 以防止它形成一个新的“快照”吗? 此外,如果您想修改一个特定项目,您只需 bag.TryTake(out item)。但是既然我已经拿到了枚举中的item,是不是又要“拿”一次呢?
任何解释/评论/示例都会非常有用。
谢谢。
【问题讨论】:
-
ConcurrentBag<T>不太可能是您尝试做的任何事情的最佳工具。该类表示一个无序的物品包,只支持一个一个地随机取出物品。您无法从此集合中删除特定项目。这是一个专门的集合,用于混合生产者-消费者场景,这在实践中极为罕见。 -
该类在内部一致性方面是线程安全的,但是,由于它包含引用,因此不能保证不会在内部共享资源的情况下让自己陷入困境。在大多数情况下,除非您有相当具体的用例,否则使用锁在概念上更容易。还有西奥多所说的
标签: c# .net multithreading concurrency