-1

I need to run tasks in parallel and transfer about 3-5 parameters to them, but now I transfer 2 parameters to the task, and as a result, I always see the value 100 in the console.

Tell me what am I doing wrong? and how to correctly pass parameters to the task?

class Program
{
    static void Main(string[] args)
    {
        /// Init
        string file_name = "unknown.dat";
        Action<string, int> action = (msg, count) => Load(msg, count);

        /// For
        for (int i = 0; i < 100; i++)
        {   
            Task.Factory.StartNew(() => action(file_name, i)); 
        }

        /// End
        Console.Read();
    }

    public static void Load(string aFileName, int aCount)
    {
        Console.WriteLine("Index: {0} ", aCount);
    }

}

enter image description here

ArchiKu
  • 41
  • 9

1 Answers1

9

This is a "captured variable" problem; try instead:

for (int i = 0; i < 100; i++)
{   
    var copy = i;
    Task.Factory.StartNew(() => action(file_name, copy)); 
}

The fundamental problem here is that your action is capturing the variable i, not the value of i at a particular time. So what happens is: your loop finishes really quickly (before the thread-pool has even got its shoes on), and i ends up at 100. At some indeterminate time the thread-pool starts processing your work items, and the i is sat at 100 for all of them. Note: it is technically possible to get earlier numbers, but that is ultimately a massive race condition.

The fix here moves the declaration of the captured variable to inside the loop; the declaration of a variable defines the scope for the purposes of captured variables, so now each copy is independent of the others.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900