Justin Bicknell
Justin Bicknell

Reputation: 4808

.NET 4.5 parallel processing and for loop

I am trying to create a list of tasks which depend on the number of processors available. I have a for loop which which seems to be behaving strangely. I am aware of the concept of closures in javascript, and it seems like something similar could be happening here:

 var tasks = new Task[Environment.ProcessorCount]; 
 for(int x = 0; x < Environment.ProcessorCount; x ++)
 {
      tasks[x] = Task.Run(() => new Segment(SizeOfSegment, x * SizeOfSegment, listOfNumbers).generateNewList());
 }

What I am finding is when I break on the line in the for loop, the variable x seems to be correct, so it starts at 0 and ends at 3 (number of processors is 4). But when I put the break point within the constructor for Segment, I am finding that x was actually 4 when stepping back in the Call Stack.

Any help would be greatly appreciated.

Upvotes: 1

Views: 1076

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500515

You're capturing x within your lambda expression - but you've got a single x variable which changes values across the course of the loop, so by the time your task actually runs, it may well have a different value. You need to create a copy of the variable inside the loop, creating a new "variable instance" on each iteration. Then you can capture that variable safely:

for(int x = 0; x < Environment.ProcessorCount; x ++)
{
    int copy = x;
    tasks[x] = Task.Run(() => new Segment(SizeOfSegment,
                                          copy * SizeOfSegment,
                                          listOfNumbers).generateNewList());
}

(I'd also advise you to rename generateNewList to GenerateNewList to comply with .NET naming conventions.)

Upvotes: 7

Related Questions