2

What is going on here? This loop most of the time just prints this:

10101010101010101010

sometimes this:

51010101010101010101

and when i debug it, it prints in order

0123456789

class Program
{
    static void Main (string[] args)
    {
        for ( int i = 0; i < 10; i++)
        {
            Task.Run(( ) => Console.Write(i));
        }
        Console.Read();
    }
}
Nikola.Lukovic
  • 1,256
  • 1
  • 16
  • 33

1 Answers1

5

If you have ReSharper installed it puts a little squiggle underneath the i:

enter image description here

with the note:

Access to modified closure

The JetBrains site gives this explanation:

This may appear to be correct but, in actual fact, only the last value of str variable will be used whenever any button is clicked. The reason for this is that foreach unrolls into a while loop, but the iteration variable is defined outside this loop. This means that by the time you show the message box, the value of str may have already been iterated to the last value in the strings collection.

(obviously their example uses a string not an int).

It "works" under debug because other things are going on and the code isn't being executed the same as it would in release.

The solution is to use a local variable:

    for ( int i = 0; i < 10; i++)
    {
        int local = i;
        Task.Run(( ) => Console.Write(local));
    }

But even then it's not guaranteed to execute in the order you expect. I just tested this and got he result:

0436215897

So each value was processed, but in indeterminate order.

ChrisF
  • 134,786
  • 31
  • 255
  • 325