我有一个并发包的作者和多个读者。
writer 定期刷新数据库中的 concurrentbag 的完整内容。
在编写器线程中重新初始化(即=新的并发包)是否线程安全?如果没有,我认为唯一的选择是在所有读取和写入期间锁定它,而这恰恰相反。我不能遍历袋子以一次清空它,因为任何读取粪便的过程都会将它们的行为基于部分信息。
谢谢你们!
我有一个并发包的作者和多个读者。
writer 定期刷新数据库中的 concurrentbag 的完整内容。
在编写器线程中重新初始化(即=新的并发包)是否线程安全?如果没有,我认为唯一的选择是在所有读取和写入期间锁定它,而这恰恰相反。我不能遍历袋子以一次清空它,因为任何读取粪便的过程都会将它们的行为基于部分信息。
谢谢你们!
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
.