Changing the incremental value of a C# Parallel.Fo

2019-04-29 15:32发布

问题:

I want to convert a for loop which increments the iterator by 2 every pass into a Parallel For loop using the TPL. The data is not order dependent or constrained in any way, but I only want to process the data in every other element of my source array (which is _Datalist in the code below), hence the need to increment by 2.

My For Loop:

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

Is it possible to tell the parallel loop that I want to increment i by two instead of one?

Here's the Parallel Loop, but obviously i is only incrementing by 1 each iteration:

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

I could tell the inner loop body to ignore odd values of i, but that seems a litle messy - is there a way of doing it in the loop initialisation somehow?

回答1:

How about:

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

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


回答2:

You can halve the number of steps and double the indices:

Parallel.For(0, _DataList.Length / 2, i =>
{
    // do work for _DataList[2 * i]                    
});


回答3:

Darin Dimitrov's answer shows an easy way to accomplish this.

However, this wasn't added, as it's typically a sign that the loop bodies aren't truly distinct. In most cases, the need to use a different increment value typically only comes with the need for processing in a specific order or other concerns that will cause parallelization to create race conditions.



回答4:

Just skip even values.

Task.Factory.StartNew(() =>
                Parallel.For(1, _DataList.Length, i =>
                {
                    if(i % 2 == 0)
                    {
                        // do work for   
                    }   
                })
            );