I\'m trying to spawn different threads for some processing. I use the for
loop index for some logic inside each thread.
How can I get the different threads to p
Answered millions of times. it is related with closure. Change your code as below
for (int j = 1; j <= 5; j++)
{
int temp = j;
tasks1.Add(Task.Factory.StartNew(() =>
{
Console.WriteLine(temp);
}, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default)
);
}
I would recomment to read this: Loop variables and Closures
Just to complete the other answers. In C# 5.0 (.NET 4.5) there was a breaking change in relation to closing over foreach
loop variable, but not to closure over for
loop variable.
See details (and preface Update note) in Eric Lippert. Closing over the loop variable considered harmful and his Closing over the loop variable, part two
Note that this issue is independent on multithreading or TPL (Task Parallel Library) usage.
The other answers and comments mentioned that it was discussed before but there was no linking to any of the previous answers. Here are some, for the sake of inter-linking:
You are 'capturing the loop variable'. The fact that j
is used inside the lambda means the compiler will treat it differently (in essence, it will be boxed) and all thread will use the same shared variable.
The short fix:
for (int j = 1; j <= 5; j++)
{
int jCopy = j;
tasks1.Add(Task.Factory.StartNew(() =>
{
Console.WriteLine(jCopy);
}, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default)
);
}