0

Good day

I am just refreshing some methods of implementation of multitasking and asynchronous methods. I came across below puzzle:

I have a list of tasks to which I add particular tasks. In the first way I add tasks using foreach loop and the second way I am adding the tasks by 'for' loop.
Using "foreach" gives me correct final results - all different according to elements of array i.e. 2,3,1,4,5.

But using the loop "for" I got all the same results i.e. 6,6,6,6,6.

If the tasks are taking proper elements of the array in "foreach" loop , why the iteration using "for" loop does not work in the same way? The code is below:

Method #1 using "foreach":

var tasks = new List<Task>();
int[] array = {1, 2, 3, 4, 5};

            foreach (var item in array)
            {
                tasks.Add(Task.Run(() => Console.WriteLine(item)));
            }
 Task.WaitAll(tasks.ToArray());

// result  is : 2,3,1,4,5  - OK

Method #2 using "for" loop:

var tasks = new List<Task>();

            for (int i = 1; i < 6; i++)
            {
                tasks.Add(Task.Run(() => Console.WriteLine(i)));
            }
 Task.WaitAll(tasks.ToArray());

// result is 6,6,6,6,6

Why 2nd method gives all the same i=6 , and why 6?? ("i" should be smaller then 6 "i<6") .

kalka79
  • 11
  • 7
  • You have a captured variable, a.k.a. a [closure](https://stackoverflow.com/questions/595482/what-are-closures-in-c). See [this answer](https://stackoverflow.com/a/271447/2791540) for a fix. – John Wu Sep 17 '21 at 14:06
  • @GSerg, sure i imagined it, the problem occurs because the lambda expression does not know that the variable i exists, therefore, it captures i on the closure, this makes some unwanted behaviour in some cases. – Rafaelplayerxd YT Sep 17 '21 at 14:08
  • @RafaelplayerxdYT The lambda knows exactly that the variable `i` exists because it's the variable that is captured, not the variable's value. The behaviour is completely documented and expected. – GSerg Sep 17 '21 at 14:09
  • Yes, it is all about closures when using "for" loop. In c# 5.0 "foreach" has been fixed for that. So with "for" loops it's better to be carefull and introduce another variable which can be used at every iteration. – kalka79 Sep 17 '21 at 16:15

0 Answers0