同时访问C#List <t>的多个索引是否安全?

时间:2019-03-26 03:19:22

标签: c# multithreading list

我有一个完整的结构列表,我想遍历并同时更改。

代码在概念上如下:

Parallel.For(0, pointsList.Count(), i=> pointsList[i] = DoThing(pointsList[i]));

我既不会添加列表,也不会从列表中删除它,只是访问和修改其项目。

我认为这很好,但是我想应该检查一下:这样可以吗,还是我需要在某个地方使用Lock以避免担心弄乱列表对象?

1 个答案:

答案 0 :(得分:4)

不保证安全。更改列表中的元素会增加列表的专用_version字段,这是各种线程可以判断列表是否已修改的方式。如果任何其他线程尝试枚举列表或使用List<T>.ForEach()之类的方法,则可能存在问题。听起来这将是极为罕见的,但这不一定是一件好事-实际上,这是最令人发指的缺陷类型。

如果您想安全起见,请创建一个新列表,而不要更改现有列表。这是解决线程问题的常见“功能”方法,可避免锁定。

var newList = pointsList.AsParallel().Select( item => DoThing(item) );

完成后,您随时可以替换旧列表。

pointsList = newList.ToList();