0

I'm testing a piece of code where a the same Task should be executed in a for loop, with variables updated every cycle.

            for (int j = 0; j < 6; j++)
            {
                _waitNextBatch++;
                Console.WriteLine($"{_waitNextBatch}");

                BatchSensor bs = new BatchSensor { SensorName = $"batch - {j}" };

                new Thread(() => SimulateBS(bs, j)).Start();
            }

In the method called by the Task I get the correct bs, but the j is the last iteration value for all the runs.

I just print the values received from the SimulateBS method

Console.WriteLine($"{bs.SensorName} | {j}");

And I get as output:

batch - 0 | 6
batch - 2 | 6
batch - 5 | 6
batch - 4 | 6
batch - 3 | 6
batch - 1 | 6

or

batch - 0 | 2
batch - 1 | 3
batch - 2 | 3
batch - 3 | 5
batch - 4 | 5
batch - 5 | 6

Any idea why is this happening?

Oiproks
  • 764
  • 1
  • 9
  • 34

1 Answers1

1

You should try this instead

var i = j;
new Thread(() => SimulateBS(bs, i)).Start();

Ultimately j is a captured variable; it is the variable itself, not the current value of the variable, that is captured - so currently all the delegates are sharing the same variable. By declaring i at a scope inside the loop, each loop iteration gets a different variable (via compiler voodoo).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
Mad hatter
  • 569
  • 2
  • 11
  • 4
    (added some words to explain *why* this should help; hope that's OK) – Marc Gravell Mar 02 '23 at 17:56
  • Thanks @Marc Gravell for the complete answer ! – Mad hatter Mar 02 '23 at 17:57
  • Thanks @MarcGravell for the answer and explanation. Is this valid also for `foreach` loop in list of objects? – Oiproks Mar 02 '23 at 18:14
  • 1
    @Oiproks it *was* at one point in C#'s history; however, it caught out so many people that they changed it - specifically the L-Value (i.e. `x` in `foreach (var x in something)` is now considered to be declared *inside* the loop for the purposes of captured variable analysis - and it no longer hurts folks – Marc Gravell Mar 02 '23 at 19:18