Reputation: 4808
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
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