0

我有一个并发包的作者和多个读者。

writer 定期刷新数据库中的 concurrentbag 的完整内容。

在编写器线程中重新初始化(即=新的并发包)是否线程安全?如果没有,我认为唯一的选择是在所有读取和写入期间锁定它,而这恰恰相反。我不能遍历袋子以一次清空它,因为任何读取粪便的过程都会将它们的行为基于部分信息。

谢谢你们!

4

1 回答 1

1

ConcurrentBag首先,这与类型无关。就这一点而言,仅此一项将是完全安全的。

如果在一个线程上对包进行方法调用,同时在另一个线程上执行以下操作:

_BagField = new ConcurrentBag<string>();

然后在第一个线程上的方法调用将很好地完成,但在旧实例上

然而,是不安全的,但由于首先使用类型的原因,从来没有

if (_BagField.Any())
    var percentage = 100 / _BagField.Count(); // broken

这可能会调用.Any()一个实例,也可能会调用另一个实例,.Count()但这从来都不是安全的,因为没有保障措施可以确保 Count 在您调用Any.

但是请注意,您不能保证其他线程会立即获取新实例。

例如,这个:

string temp;
while (!_Bag.TryTake(out temp))
{
    // process temp
}

可能永远不会到达新实例,并且会在停止之前继续处理旧包实例。

为确保这一点,请确保包含包引用的字段为volatile.

于 2013-07-12T23:09:15.973 回答