2016-12-01 5 views

ответ

7

С

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; 
    ... 
}); 
3

Третий параметр - delegate. Поэтому в каждой итерации вы можете указать, что будет делать ваша индексирующая переменная внутри делегата.

EDIT: Ok нашел рабочий раствор: Как уже предложил Дмитрий Быченко вы все равно должны начать с 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]); 
}); 
+1

Это не делает то, что он просит. ваш код запускается для значений 5, 6, 7, 8, 9 параллельно, в то время как он хочет, чтобы он был эквивалентен циклу, который пропускает каждый второй элемент (значения: 3, 5, 7). –

+0

Обратите внимание, что изменение 'i' внутри' делегата' не меняет счет 'Parallel.For', и это только скопированный тип значения -' int'. –

+0

Я вижу это! вы совершенно правы. –

1

Дмитрий ответ Быченко добудет его, но вы также можете реализовать свой собственный 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

Смежные вопросы