2

Кто-нибудь знает, почему этот код возвращает исключение из диапазона?
Например, если экземпляр leastAbstractions List имеет count == 10, цикл выполнит 11 раз, заканчивая i = 10, и возвращает это исключение.Параллельный код бросает OutOfRangeException

for (int i = 0; i < leastAbstractions.Count; i++) 
{ 
    Task.Factory.StartNew((object state) => 
    { 
     this.Authenticate(new HighFragment(leastAbstractions[i])).Reactivate(); 
    }, TaskCreationOptions.PreferFairness); 
} 

ответ

4

Ваш цикл не фактически выполнение 11 раз - это только выполнение в 10 раз, но я == 10 к тому времени некоторые из этих задач выполнения.

Это обычная проблема - вы захватываете переменную цикла в выражении лямбда. Просто возьмите копию счетчика, а также захватить, что вместо того, чтобы:

for (int i = 0; i < leastAbstractions.Count; i++) 
{ 
    int copy = i; 
    Task.Factory.StartNew((object state) => 
    { 
     this.Authenticate(new HighFragment(leastAbstractions[copy])) 
            .Reactivate(); 
    }, TaskCreationOptions.PreferFairness); 
} 

Таким образом, когда ваша задача выполняется, вы увидите текущее значение «экземпляра» из copy, что вы захватили - и это значение никогда изменяется, в отличие от значения i.

Просмотреть записи пользователя Eric Lippert: part 1; part 2.

+0

Я думал, что счетчик передается в качестве аргумента сразу при создании новой задачи. Наверное, я ошибся. Благодарю. – pevogam

+0

@blaze: Вы используете счетчик * в выражении лямбда *. Когда выполняется выражение лямбда, используется значение * current * того, что вы захватываете. Это должно произойти в другом потоке, потому что это выражение лямбда - это то, что ваша задача должна делать. –

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