5

我可以改变我的循环

for (int i = 0; i < something; i++)

至:

Parallel.For(0, something, i =>

但是如何用这个循环做到这一点?:

for (i = 3; i <= something / 2; i = i + 2)

感谢您的回答。

4

3 回答 3

9

自从

for (int i = 3; i <= something / 2; i = i + 2)
{
    ...
}

可以改写成

for (int k = 1; k < (something + 2) / 4; ++k)
{
    int i = 1 + 2 * k;
    ...
}

你可以把

Parallel.For(1, (something + 2) / 4, k =>
{
    int i = 1 + 2 * k; 
    ... 
});
于 2016-12-01T15:44:07.730 回答
3

第三个参数是一个delegate。所以每次迭代你都可以指定你的索引变量在委托中应该做什么。

编辑: 好的,找到了一个可行的解决方案:正如 Dmitry Bychenko 已经建议的那样,您仍然应该从 0 开始,只需添加startValue作为偏移量

int something = 16;

int startValue = 3;
int stepSize = 2;

List<int> numbers = Enumerable.Range(0, 20).ToList();

Parallel.For(0, something / 2, i => 
{
    int ind = (stepSize * i) + startValue ; Console.WriteLine(numbers[ind]);
});
于 2016-12-01T15:38:54.477 回答
1

Dmitry Bychenko的答案明白了,但您也可以使用自定义步骤实现自己的ParallelFor,这将使您的代码更具可读性:

static void ParallelFor(int start, int last, Func<int, int> step, Action<int> action)
{
    var enumerable = StepEnumerable<int>
        .Create(start, step)
        .TakeWhile(x => x < last);

    Parallel.ForEach(enumerable, action);
}

这是StepEnumerable的实现:

public class StepEnumerator<T> : IEnumerator<T>
{
    ...

    public StepEnumerable(T value, Func<T, T> manipulation)
    {
        mEnumerator = new StepEnumerator<T>(value, manipulation);
    }

    public static StepEnumerable<T> Create(T value, Func<T, T> manipulation)
    {
        return new StepEnumerable<T>(value, manipulation);
    }

    ...
}

public class StepEnumerator<T> : IEnumerator<T>
{
    public bool MoveNext()
    {
        Current = mManipulation(Current);
        return true;
    }
}

然后,例如,如果您运行以下代码:

ParallelFor(3, 16, x => x + 2, Console.WriteLine);

您将获得以下输出(当然在单独的行中):

5、11、7、13、9、15

于 2016-12-04T07:21:25.077 回答