0

I am learning about multithreading in C#. It is making me hard, so I am doing some simple programs to understand it better.

I realized that if I have:

   static void Main()
    {
        Task[] tasks = new Task[4];
        for (int i = 0; i < 4; i++)
        {
            tasks[i] = Task.Factory.StartNew(() => {
                Console.WriteLine(i);
            });
        }
        Console.ReadKey();
    }

The output is 4444, no 0123 like I expected. Why is it?

EDIT:

Sadiq said in his answer that the reason of this behaviour is because i'm closing over a loop variable. But if I add to my code Thread.sleep(500); outside the lambda statement and inside the loop, I get 0123. So, why this behaviour supposedly caused by clousures don't occurs with adding this line of code?

it seems to me that the reason of the asked behaviour is other. The code for if you don't understand what I've just written:

static void Main()
    {
        Task[] tasks = new Task[4];
        for (int i = 0; i < 4; i++)
        {
            tasks[i] = Task.Factory.StartNew(() => {
                Console.WriteLine(i);
            });
            Thread.Sleep(500); 
        }
        //Now the output is: 0123
        Console.ReadKey();
    }
Community
  • 1
  • 1
Pablo De Luca
  • 795
  • 3
  • 15
  • 29
  • "why this behaviour supposedly caused by clousures don't occurs with adding this line of code" - because you're now waiting 500 milliseconds between each iteration of the loop, thus allowing the `Task` to run to completion on the captured variable before the next iteration of the loop updates that same variable. – Damien_The_Unbeliever Aug 05 '16 at 06:44

1 Answers1

2

Make a local variable - copy the value into it and you should get the expected output:

static void Main()
{
    Task[] tasks = new Task[4];
    for (int i = 0; i < 4; i++)
    {
        int x = i;
        tasks[x] = Task.Factory.StartNew(() => {
            Console.WriteLine(x);
        });
    }
    Console.ReadKey();
}

The reason you get the unexpected output is because i gets shared. You are closing over a loop variable.

Sadique
  • 22,572
  • 7
  • 65
  • 91