0

I have a problem with my multi threading app.
I have an array with 4 Threads in it.
Here is how I initialize them:

for (int i = 0; i < threads.Length; i++)
{
    threads[i] = new Thread(delegate () { ThreadMethod(i); });
}

But after my first test(s) I showed that all four threads run with 3 as passed value.
I chagend it to

for (int i = 0; i < threads.Length; i++)
{
    int id = i;
    threads[i] = new Thread(delegate () { ThreadMethod(id); });
}

and it worked but for me it looks like there must be a better way to pass my i to my thread.

Am I right with my guess and if I am, how should I pass i?

Thank you!

BDevGW
  • 347
  • 3
  • 15
  • 1
    This is correct and expected. It's called a "closure around the variable i". See [What are closures in .Net](https://stackoverflow.com/questions/428617/what-are-closures-in-net). To answer your question, assigning `i` to another variable and using that inside the delegate is the correct approach. –  Jan 10 '20 at 19:10

1 Answers1

1

The closure uses local variables -- in a for loop the variables declared for the loop are not local they have to be inside the block ({}) for that. That is why the 2nd example works.

The delegate keyword is what creates the closure and it looks for local variables to include in the closure. When it finds id it includes it. When it doesn't it references the global (outside the closure) value of i and at the time of running i has a value of 3.

Hogan
  • 69,564
  • 10
  • 76
  • 117
  • You mean it's like I would pass it with ```ref``` so when I start them later they all uses the same ```i``` which has a value of ```3```once I completed the loop? – BDevGW Jan 10 '20 at 20:07
  • @BDevGW -- yes variables that are not "in the closure" are references to the external variable -- they all point to the same i. – Hogan Jan 13 '20 at 18:31
  • Ok, still a little bit confusing but I think I can keep this in mind :) – BDevGW Jan 13 '20 at 18:34
  • 1
    @BDevGW -- I think of closures as a little room that gets added to the thread -- in the first one `i` is not in the room and in the 2nd it is. – Hogan Jan 13 '20 at 18:37