C#Parallel.ForEach是否对集合的迭代使用相同的线程

Ron*_*Ron 6 c# parallel-processing foreach multithreading task-parallel-library

我有一个IEnumerable,我想传递给Parallel.ForEach,但IEnumerable是使用C#方法和yield实现的,并且枚举器中的代码可能不是线程安全的.计划在此使用Parallel.ForEach.我假设ForEach的IEnumerable的实际内部迭代总是在同一个线程上,然后ForEach将每个项目传递给潜在的其他线程进行处理.它是否正确?

我读过IEnumerable迭代使用线程本地存储的地方,访问相同IEnumerable的不同线程将各自拥有自己的迭代当前,下一步等.这就是为什么我假设ForEach实际上会在同一个线程上进行所有迭代.

我至少知道迭代不在调用Parallel.ForEach的同一个线程上.有点希望它是因为我需要为正在进行迭代的线程做一些线程初始化.所以这里可能有一个问题是在执行迭代的线程上注入我的初始化.

Ser*_*rvy 6

编写一个可以安全地从多个线程迭代的东西是不可能的IEnumerator.API本质上反对允许这种行为.因为Parallel.ForEach没有可能的选择,只能从单个线程枚举序列.为了直接将迭代器暴露给每个生成的线程,它需要使用与IEnumerator/ IEnumerableexpose 不同的API .

  • @Stilgar不,你无法安全地从多个线程枚举一个枚举器.首先,这样做的全部意义是对"MoveNext"*的调用不会被同步.这就是它们被设计为从多个线程安全枚举的意义.另外,人们永远无法确定"当前"的值是否实际应用于线程所做的移动; 你会看到两个线程同时移动迭代器,然后两个线程都使用第二个移动的当前值. (3认同)