我一直在阅读各种各样的东西,看起来这应该有用,但我想确定一下。我有一个静态属性,应该是一个缓存(加上一些与缓存数据相关的其他功能)。它将实际数据存储在ConcurrentBag中,它有一个IEnumerable方法来[过滤和]从这个包中产生返回值。它会像这样自我更新:
ConcurrentBag<Foo> NewBag = GetNewThings();
Cache = NewBag;
从我所读过的内容来看,这似乎应该有效,尽管我没有预料到这一点。我预计这会炸掉任何正在读取的迭代器。但是我读到如果另一个线程正在遍历旧列表,它将在新列表被交换时在列表的该实例上完成。第二个(新)线程将在新列表上启动,即使旧线程仍在迭代旧实例。这看起来很神奇,所以我可能错了,是吗?
其他线程只迭代列表,唯一的写入就是在这两行上进行的。
答案 0 :(得分:3)
我读到如果另一个线程正在迭代旧列表,那么 当新列表获得时,将在列表的该实例上完成 交换。第二个(新的)线程将在新列表上开始,即使是 旧线程仍在迭代旧实例。这个 看起来很神奇,所以我可能错了,是吗?
你读的是正确的。
这是线程安全的,但您可能希望创建变量volatile
或使用Volatile.Read
和Volatile.Write
以确保所有线程的即时可见性。
答案 1 :(得分:2)
分配给Cache
的原始实例仍然存在,并且是旧线程迭代的实例。
新线程对GetNewThings()
结果进行操作。