0

Possible Duplicate:
C# - The foreach identifier and closures
From Eric Lippert’s blog: “don’t close over the loop variable”

I'm using a lambda expression as ThreadStart parameter, to run a method in a new thread using Thread class. This is my code:

delegate void del();

static void Do(int i)
{
    Console.WriteLine(i);
}

static del CreateLoop(del Do)
{
    return () =>
    {
        while (true)
        {
            Do();
            Thread.Sleep(500);
        }
    };
}

static void Main(string[] args)
{
    int n = 0;
    var loop = CreateLoop(() => Do(n));
    new Thread(() => loop()).Start();
    Thread.Sleep(500);
    n = 1;
}

And this is the output:

0
1
1
1
...

How is it possible?
Why if I change the value of my integer variable n, also changes the value of i (Do's parameter)?

Community
  • 1
  • 1
gliderkite
  • 8,828
  • 6
  • 44
  • 80

2 Answers2

0

You should make a different variable out of it, thus not changing the original value.

After all, all you're really doing is calling that same old 'function', the lambda expression passing the variable i over and over again, which indeed changes. It's nog like you're storing the initial value of the var i somewhere.

Daneo
  • 508
  • 3
  • 17
0
var loop = CreateLoop(() => Do(n));

This line is simply creating a new function and assigning it to a variable. This function, among other things, passes the value n to the Do function. But it's not calling the Do function, it's just creating a function which will, when executed, call the Do function.

You then start a new thread which calls the function, etc, but your new thread is still executing Do(n), passing the n variable to Do. That part doesn't change - you've created a function which references a particular place in memory (represented by the variable n) and continues to reference that place in memory even as you change the value which is stored there.

I believe the following would "fix" your code:

var loop = (int x) => () => CreateLoop(() => Do(x));
new Thread(loop(n)).Start();

This passes the value of n to the function represented by loop, but the loop function creates a new place in memory (represented by x) in which to store the value. This new place in memory is not affected by subsequent changes to n. That is to say, the function you've created does not directly reference the place in memory to which n is a pointer.

JDB
  • 25,172
  • 5
  • 72
  • 123