【发布时间】:2015-02-05 01:20:00
【问题描述】:
我一直在阅读各种内容,看起来这应该可行,但我想确定一下。我有一个静态属性,它应该是一个缓存(加上一些与缓存数据相关的其他功能)。它将实际数据存储在 ConcurrentBag 中,并且它有一个 IEnumerable 方法来[过滤并] 从这个包中产生返回值。它会像这样更新自己:
ConcurrentBag<Foo> NewBag = GetNewThings();
Cache = NewBag;
从我读到的内容来看,这似乎应该可行,尽管我没想到它会这样。我希望这会在发生这种情况时炸毁正在读取的任何迭代器。但是我读到如果另一个线程正在遍历旧列表,它将在列表的该实例上完成,而新列表被交换。第二个(新)线程将在新列表上启动,即使旧线程仍在迭代它们的旧实例。不过这看起来很神奇,所以我可能错了,是吗?
其他线程只迭代列表,唯一的写入发生在这两行。
【问题讨论】:
-
请注意,只有一小部分“魔术”与线程相关(事实上,指针大小的赋值是原子的),其余的行为可以很容易地在单线程同步代码中看到 - 改变值保存集合的变量对集合本身及其迭代器没有影响。
-
线程安全不是传递属性。您不能通过迭代来破坏 ConcurrentBag 的事实确实not 意味着您的 代码是线程安全的。很少有,处理不再在包中的对象或在开始迭代后没有看到任何添加的对象很少会得到很好的结果。
标签: c# multithreading