我有一位作家和多个并发包的读者。
作者定期从数据库刷新concurrentbag的完整内容。
在编写器线程中重新初始化(即= new concurrentbag)是否安全?如果没有,我看到唯一的选择是在所有读取和写入期间将其锁定,而不是取消这一点。我不能在袋子上迭代一次清空一块,因为任何读取粪便的过程都会根据部分信息将其行为作为基础。
谢谢大家!
答案 0 :(得分: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
。