2

I have a problem with array of threads in C#. When I start threads if for loop and send in parameter some threads get same value.

Thread[] nit = new Thread[n];

for (int i = 0; i < n; i++)
{
    nit[i] = new Thread(() => functionThread(i + 1)); //functionThread => thread
    nit[i].IsBackground = true;
    nit[i].Name = string.Format("Thread: {0}", i + 1);
    nit[i].Start();
    Thread.Sleep(500); //I have problem here
}

for (int i = 0; i < n; i++)
{
    nit[i].Join();
}

If n = 4 the values in threads should be 1, 2, 3, 4. But if i remove "Thread.Sleep(500);" or i set value less than 500 the values become for example 2, 2, 3, 4.

How could I make this work without Thread.Sleep() and still have correct values in threads?

Thank you in advance.

JanSLO
  • 388
  • 2
  • 9

1 Answers1

0

Try this:

int iLocal = i;
nit[i] = new Thread(() => functionThread(iLocal + 1)); //functionThread => thread

It happens because you are passing a variable, instead of the value. This is similiar problem: Captured variable in a loop in C#

You can learn more about closures from Jon's post: http://csharpindepth.com/Articles/Chapter5/Closures.aspx

Community
  • 1
  • 1
Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
  • I'm not sure "It happens because you are passing a variable, instead of the value. " is really an accurate explanation of why this is happening. It has to do with the timing of when the captured `i` is accessed in `functionThread` - whether it's before the loop increments it or after. – lc. Jan 20 '15 at 17:01
  • @lc. And the reason that the timing is relevant is because the closure closes over the *variable*, not the *value*. Had the closure closed over the *value* that timing wouldn't have been relevant. – Servy Jan 20 '15 at 17:03
  • @Servy Ahh, now I understand what that sentence was getting at. Sorry, it just didn't make sense to me the first three times I read it (time for bed?). Thanks for the clarification. – lc. Jan 20 '15 at 17:06