aharon
aharon

Reputation: 7643

array of threads c#

i have this code:

    Thread[] threadsArray = new Thread[4];
        for (int i = 0; i < 4; i++)
        {
            threadsArray[i] = new Thread(() => c1.k(i));
        }
        for (int i = 0; i < 4; i++)
        {
            threadsArray[i].Start();
        }
        for (int i = 0; i < 4; i++)
        {
            threadsArray[i].Join();
        }

the function k is this:

void k(int i)
{
    while(true)
      Console.WriteLine(i);
}

for some reason just the last thread is running and printing 4444444.... why aren't all the threads running?

Upvotes: 11

Views: 30009

Answers (3)

KUL
KUL

Reputation: 491

Thread[] threadsArray = new Thread[4];
for (int i = 0; i < 4; i++)
{
    //better use ParameterizedThreadStart Delegate
    threadsArray[i] = new Thread(k);
}
for (int i = 0; i < 4; i++)
{
    //passing the value to the function
    threadsArray[i].Start(i);
}
for (int i = 0; i < 4; i++)
{
    threadsArray[i].Join();
}

//changing the input data type
void k(object i)
{
    while (true)
        Console.WriteLine((int)i);
}

Upvotes: 0

Winston Smith
Winston Smith

Reputation: 21882

You are closing over the i variable.

Try this instead

for (int i = 0; i < 4; i++)
{
    int x = i;
    threadsArray[i] = new Thread(() => c1.k(x));
}

Upvotes: 4

SLaks
SLaks

Reputation: 887413

All of the threads are printing the same variable.

Your lambda expression (() => c1.k(i)) captures the i variable by reference.
Therefore, when the lambda expression runs after i++, it picks up the new value of i.

To fix this, you need to declare a separate variable inside the loop so that each lambda gets its own variable, like this:

    for (int i = 0; i < 4; i++)
    {
        int localNum = i;
        threadsArray[i] = new Thread(() => c1.k(localNum));
    }

Upvotes: 30

Related Questions