2

Does anyone know how why this code returns out of range exception?
For example if the leastAbstractions List instance has count == 10, the loop will execute 11 times finishing with i = 10 and returning this exception.

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

1 Answer 1

4

Your loop isn't actually executing 11 times - it's only executing 10 times, but i == 10 by the time some of those tasks execute.

It's the normal problem - you're capturing a loop variable in a lambda expression. Just take a copy of the counter, and capture that instead:

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

That way, when your task executes, you'll see the current value of the "instance" of copy that you captured - and that value never changes, unlike the value of i.

See Eric Lippert's blog posts on this: part 1; part 2.

Sign up to request clarification or add additional context in comments.

2 Comments

I thought that the counter is passed as an argument immediately in the creation of the new task. I guess I was wrong. Thanks.
@blaze: You're using the counter in the lambda expression. When the lambda expression is executed, the current value of whatever you're capturing is used. That has to happen in a different thread, because that lambda expression is what your task is meant to do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.