6

TPL を使用して、パスごとに反復子を 2 ずつインクリメントする for ループを並列 For ループに変換したいと考えています。データは順序に依存したり制約されたりすることはありませんが、ソース配列の他のすべての要素 (以下のコードでは _Datalist) のデータのみを処理したいので、2 ずつインクリメントする必要があります。

私のForループ:

for (int i = 1; i < _DataList.Length - 1; i += 2)
{
     // Do work for _DataList[i]
}

i を 1 ではなく 2 ずつインクリメントすることを並列ループに伝えることはできますか?

ここに並列ループがありますが、明らかに i は反復ごとに 1 だけ増加します。

        Task.Factory.StartNew(() =>
            Parallel.For(1, _DataList.Length, i =>
            {
                // do work for _DataList[i]                    
            })
        );

i の奇数の値を無視するように内側のループ本体に指示することもできますが、それは少し厄介なようです。ループの初期化で何らかの方法でそれを行う方法はありますか?

4

4 に答える 4

12

ステップ数を半分にし、インデックスを2倍にすることができます。

Parallel.For(0, _DataList.Length / 2, i =>
{
    // do work for _DataList[2 * i]                    
});
于 2010-10-20T16:50:56.640 に答える
11

どうですか:

var odds = Enumerable.Range(1, _DataList.Length).Where(i => i % 2 != 0);

Task.Factory.StartNew(() =>
    Parallel.ForEach(odds, i =>
    {
        // do work for _DataList[i]                    
    })
);
于 2010-10-20T16:56:02.117 に答える
1

Darin Dimitrov の答えは、これを達成する簡単な方法を示しています。

ただし、これは通常、ループ本体が完全に区別されていないことを示しているため、追加されませんでした。ほとんどの場合、別のインクリメント値を使用する必要があるのは、通常、特定の順序で処理する必要があるか、並列化によって競合状態が発生するその他の懸念がある場合のみです。

于 2010-10-20T17:03:21.067 に答える
0

偶数の値をスキップするだけです。

Task.Factory.StartNew(() =>
                Parallel.For(1, _DataList.Length, i =>
                {
                    if(i % 2 == 0)
                    {
                        // do work for   
                    }   
                })
            );
于 2015-09-19T08:14:57.460 に答える