2012-12-26 43 views
8

有没有什么办法可以实现for这个循环的Parallel.For版本?Parallel.For使用步骤= 1

for (int i = 0; i < 100; i += 2) { DoStuff(i); } 

我没有看到一个接受step参数的重载,尽管我想不出任何理由,这在逻辑上是不可能的。使用Enumerable.Range

接受的答案thisthis问题建议在一系列int S使用Parallel.ForEach产生的,但对我来说,我使用线程本地数据 所以 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; 
     ); 
    } 
); 

回答

14

这里有一个提示:

for (int j = 0; j < 50; j++) { i = 2*j; DoStuff(); } 

一般来说,看你能不能找出迭代次数和迭代次数的变量值转换。

+2

一点也不像一个可笑的简单的解决方案后,工作了我,使我感到自己很笨:) 谢谢。 – Rotem

3

本的建议是非常好的恒定步骤,例如+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数组中获得数据。你可以取代inputEnumerable.Range(或With等结合起来)

这将完全正常工作,如果你想获得在i变量只有素数。

+0

我不知道为什么我以前错过了'Parallel.ForEach'的线程局部重载,我认为线程局部只在'Parallel.For'中可用。谢谢 – Rotem

3

这里是另一种方式来处理阶梯式指数

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; 
      } 
     } 
0

全胜的回答转换成VB.NET的新的迭代函数

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