更改C#Parallel.For循环的增量值

更改C#Parallel.For循环的增量值,c#,parallel-processing,task-parallel-library,C#,Parallel Processing,Task Parallel Library,我想使用TPL将每次迭代器递增2的for循环转换为并行for循环。数据不依赖于顺序或以任何方式受到约束,但我只想处理源数组(下面代码中为_Datalist)中其他每个元素中的数据,因此需要增加2 我的For循环: for (int i = 1; i < _DataList.Length - 1; i += 2) { // Do work for _DataList[i] } 我可以告诉内部循环体忽略I的奇数值,但这似乎有点混乱-有没有办法在循环初始化中做到这一点?您可以将步骤数

我想使用TPL将每次迭代器递增2的for循环转换为并行for循环。数据不依赖于顺序或以任何方式受到约束,但我只想处理源数组(下面代码中为_Datalist)中其他每个元素中的数据,因此需要增加2

我的For循环:

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

我可以告诉内部循环体忽略I的奇数值,但这似乎有点混乱-有没有办法在循环初始化中做到这一点?

您可以将步骤数减半,将索引加倍:

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

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

Task.Factory.StartNew(() =>
    Parallel.ForEach(odds, i =>
    {
        // do work for _DataList[i]                    
    })
);
显示了实现此目标的简单方法

然而,这并没有被添加,因为这是一个典型的信号,表明循环体并不是真正不同的。在大多数情况下,需要使用不同的增量值通常只需要按照特定顺序进行处理,或者需要考虑其他会导致并行化以创建竞争条件的问题。

只需跳过偶数值即可

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

不要只忽略奇数值;这会创建两倍于您需要的任务,这会增加许多不必要的开销。是的,我明白您的意思,请注意以供将来参考,但在我应用此循环的情况下,元素的处理顺序实际上不是一个简单的顺序concern@Gareth当前位置我之所以提到这一点,是因为实际上有一次讨论(我找不到)Stephen Toub特别提到了为什么Parallel.For没有添加此功能,这基本上归结为它对于并行处理来说通常是有问题的,但您始终可以通过partitioner或Parallel.foreach解决它。我相信在.NET中使用SIMD指令时,此用例会非常自然地出现,由于它们是通过创建
矢量来操作的,您能解释一下您的答案吗?通常认为,为你给出的答案提供一些信息或解释是一种良好的做法。这可能有助于未来的用户或OP更多。这不是一个好主意,因为你正在创造开销,而这正是我试图避免的——请参阅关于这个问题的第一条评论。幸运的是,5年前有一些很好的解决方案:)
Task.Factory.StartNew(() =>
                Parallel.For(1, _DataList.Length, i =>
                {
                    if(i % 2 == 0)
                    {
                        // do work for   
                    }   
                })
            );