-1

im starting 10 tasks to get result from web api. Im get IndexOutOfRangeException on offsets array. But how its posible. Actually 'i' variable canot be greater or equal that 10. Can anyone help with this? For loop not working corectly?

            times = 10;
            Task[] tasks = new Task[times];
            int[] offsets = new int[times];

            for (int i = 0; i < times; i++)
            {
                offsets[i] = offset;
                tasks[i] = Task.Run(() => SearchLocalByQuery(query, offsets[i], (i + 1)));
                offset += Limit;
            }
            Task.WaitAll(tasks);

i = 10,

i cannot be 10 in for loop off this example.

System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'

4
  • i cannot be 10 in for loop off this example. I see an i + 1 though. Commented May 1, 2019 at 14:57
  • please clarify, offset, Limit and SearchLocalByQuery. offset += Limit looks suspicious to me. Commented May 1, 2019 at 15:02
  • this is just a parameter function SearchLocalByQuery. not increment 'i' variable. Commented May 1, 2019 at 15:04
  • in one request i can get max 100 items. Limit is how many units i want. if i want 1000 units use offset variable. SearchLocalByQuery call to web api and return result Commented May 1, 2019 at 15:06

1 Answer 1

2

i cannot be 10 in for loop off this example.

It can be in the lambda expression. This expression:

() => SearchLocalByQuery(query, offsets[i], (i + 1))

captures the variable i, and will evaluate that variable value whenever it is executed. Task.Run returns immediately but won't necessarily have started executing the delegate yet - so it's entirely possible that the loop has moved onto the next iteration, or completed, before i is evaluated.

The simple fix for this is to declare a local variable to capture i inside the loop:

for (int i = 0; i < times; i++)
{
    int copy = i;
    offsets[i] = offset;
    // Make sure we only use copy within the lambda expression
    tasks[i] = Task.Run(() => SearchLocalByQuery(query, offsets[copy], copy + 1));
    offset += Limit;
}

Now there'll be a fresh copy variable for each iteration of the loop, and that variable will never change its value - so the lambda expression will execute using "the value of i for that iteration of the loop" regardless of what the current value of i is.

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

1 Comment

Thank you. It helped. Im add copy off 'i' variable.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.