有没有办法实现此Parallel.For
循环的for
版本?
for (int i = 0; i < 100; i += 2) { DoStuff(i); }
我没有看到接受步骤参数的重载,但我想不出任何理由这在逻辑上是不可能的。
this和this问题的已接受答案建议在使用Parallel.ForEach
生成的int
范围内使用Enumerable.Range
,但就我而言,我是使用线程本地数据所以。Parallel.ForEach
不是选项
另一种选择是检查我的循环体i % 2 == 0
中是否return
,但这仍然执行线程本地数据初始化器Func
和终结器Func
。以下是演示此选项的代码段:
Parallel.For<Bar>(0, limit,
() => new Bar(), //thread local data initialize
(i, state, local) => //loop body
{
if (i % 2 != 0) return local;
local.foo += DoStuff(i);
return local;
},
(local) => //thread local data post-action
{
lock (loopLocker)
{
globalData.foo += local.foo;
);
}
);
答案 0 :(得分:14)
这是一个提示:
for (int j = 0; j < 50; j++) { i = 2*j; DoStuff(); }
一般来说,看看你是否可以计算出迭代次数以及从迭代次数到变量值的转换。
答案 1 :(得分:4)
这是处理步进索引的另一种方法
private void ParallelForEachProcessSteppedIndexes()
{
Parallel.ForEach(SteppedIterator(0, 100, 2), (index) => DoStuff(index));
}
private static IEnumerable<int> SteppedIterator(int startIndex, int endIndex, int stepSize)
{
for (int i = startIndex; i < endIndex; i = i + stepSize)
{
yield return i;
}
}
答案 2 :(得分:3)
Ben的建议对于恒定步骤是非常好的,例如+ 2,+ 3等。
或者(如果您的步骤是随机的)您可以使用Parallel.ForEach
例如
int[] input = { 1, 3, 4, 5, 7, 10, 20, 25 };
Parallel.ForEach(input,
() => new Bar(), //thread local data initialize
(i, state, local) => //loop body
{
// your code
},
(local) => //thread local data post-action
{
// your code
}
变量i
将从input
数组中获取数据。您可以将input
替换为Enumerable.Range
(或将其与With
等结合使用。)
如果您想在i
变量中仅获得素数,那将完全正常。
答案 3 :(得分:0)
Toan的答案在转换为VB.NET的新Iterator功能后为我工作
Private Sub LoopExample()
Parallel.ForEach(SteppedIterator(1,100,5), AddressOf Test)
End Sub
Private Iterator Function SteppedIterator(startIndex As Integer, endIndex As Integer, stepSize As Integer) As IEnumerable(Of Integer)
For i As Integer = startIndex To endIndex Step stepSize
Yield i
Next
End Function
Private Sub Test(i As Integer, state As ParallelLoopState, index As Long)
Debug.WriteLine(i.ToString)
End Sub