It works fine!
All you have to do is remember when things happen.
Action<int32> action = arg =>
{
for (Int32 i = 0; i < arg; i++)
{
Thread.Sleep(700);
Console.WriteLine("Result : " + (number += i));
}
};</int32>
Sets up the delegate. Nothing gets executed yet.
action.BeginInvoke(5,
arg =>
{
Console.WriteLine("action complete, result = {0}", (Int32)arg.AsyncState);
IsComplete = true;
},
number);
Evaluates all parameters, then starts the invoke. The parameters evaluate to:
A constant: 5
An anonymous delegate.
The current value of Number: 0
The thread is then created, and starts. But, the anonymous delegate that is executed when it finishes already has it's parameters ready: 0
while (!IsComplete)
{
Thread.Sleep(500);
Console.WriteLine("Main is doing more...");
}
Waits for the invoked thread to complete.
So, when the thread complete, it prints zero, not the final value of number.
When you change "number" to "10" the parameter evaluation is of a constant value.
To prove it, make the initial value of number -6 and see what happens!