8

このループ のParallel.Forバージョンを達成する方法はありますか?for

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

これが論理的に不可能な理由は考えられませんが、step パラメーターを受け入れるオーバーロードは見当たりません。

thisおよびthis questionに対する受け入れられた回答は、 を使用して生成された s のParallel.ForEach範囲で使用することを示唆していますが、私の場合、スレッド ローカル データを使用しているため、オプションではありませんintEnumerable.RangeParallel.ForEach

もう 1 つのオプションはi % 2 == 0、ループの本体内にあるかどうかを確認することとreturn、これでもスレッド ローカル データの intializerFuncと finalizerを実行すること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;
        );
    }
);
4

4 に答える 4

6

ステップインデックスを処理する別の方法は次のとおりです

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;
            }
        }
于 2012-12-27T10:31:13.290 に答える
4

ベンの提案は、+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.RangeWith

変数で素数のみを取得したい場合、それは完全にうまく機能しiます。

于 2012-12-26T19:41:21.183 に答える
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
于 2017-04-11T13:02:05.450 に答える