I have created one function named printInteger() as
static void printInteger(object i)
{
Console.Write(i + " ");
}
I am creating 10 threads using a for loop and passing integer as an argument via two methods. First Method : passing argument through start()
for(int i=0;i<10;i++)
{
new Thread(printInteger).Start(i);
}
Output in this case is : 1 2 3 5 0 4 6 8 7 9
Second Method : passing argument through Lambda expression
for(int i=0;i<10;i++)
{
new Thread(() =>printInteger(i)).Start();
}
Output in this case is : 2 4 3 4 5 7 8 8 9 10
Behaviour first : As thread will execute in any order, so non increasing order of the Integers is expected.
Behavior second : As i variable refers to the same memory location throughout the loop’s lifetime, so it is also expected that value of i might change during
runtime.
My Question is:
- Why the result in First Method and the Second Method is different?
- We can see both the methods are behaving as a Behavior first. But why only the second method behaving as a Behavior second?
Why the result in First Method and the Second Method is different?
Because in the first approach you're passing the value of i
to the Thread.Start
method as its initial state. That is evaluated at the time you call Start
.
In the second approach, you're capturing i
in your lambda expression. It's evaluated at the point of execution. All your threads will refer to the same variable, and print out the value of the variable at the time they execute.
If you want to use a lambda expression but have each thread capture a different variable, simply introduce a new variable inside the loop:
// I've renamed the method it calls to be more idiomatic
for (int i = 0; i < 10; i++)
{
// Each iteration creates a separate "copy" variable
int copy = i;
new Thread(() => PrintInt32(copy)).Start();
}
See more on this question at Stackoverflow