e36*_*6M3 12 .net c# asp.net multithreading
我有一个填充a的主线程List<T>.此外,我创建了一个将在不同线程上执行的对象链,需要访问List.原始列表在生成后永远不会被写入.我的想法是将列表传递IEnumerable<T>给在其他线程上执行的对象,主要是因为不允许那些实现这些对象的人错误地写入列表.换句话说,如果保证不写入原始列表,多个线程使用.Where或foreachIEnumerable是否安全?
如果原始集合永远不会改变,我不确定迭代器本身是否是线程安全的.
And*_*rey 12
IEnumerable<T>无法修改.那么什么可以是非线程安全的呢?(如果你不修改实际List<T>).
对于非线程安全,您需要编写和读取操作.
"迭代器本身"是为每个实例化的foreach.
编辑:我简化了我的回答,但@Eric Lippert补充了有价值的评论.IEnumerable<T>没有定义修改方法,但它并不意味着接入运营商是线程安全的(GetEnumerator,MoveNext等),最简单的例子:GetEnumerator因为这实现的:
IEnumerator更复杂的例子是缓存.
这是有趣的一点,但幸运的是我不知道任何没有线程安全实现的标准类IEnumerable.
调用Where或foreach的每个线程都有自己的枚举器 - 它们不共享同一列表的一个枚举器对象.因此,由于未对List进行修改,并且由于每个线程都使用自己的枚举器副本,因此不应存在线程安全问题.
您可以在一个线程中看到这个 - 只需创建一个包含10个对象的List,并从该List中获取两个枚举器.使用一个枚举器枚举5个项目,并使用另一个枚举5个项目.您将看到两个枚举器仅通过前5个枚举枚举,而第二个枚举器没有从第一个枚举器停止的位置开始.
只要您确定List不会修改,就可以安全地从多个线程读取。这包括使用IEnumerator它提供的实例。
对于大多数收藏来说都是如此。实际上,BCL中的所有集合在枚举过程中都应保持稳定。换句话说,枚举器将不会修改数据结构。我可以想到一些模糊的情况,例如splay树,在枚举它可能会修改结构。同样,没有BCL集合会这样做。
| 归档时间: |
|
| 查看次数: |
6860 次 |
| 最近记录: |