Hi in the following example,
void Main()
{
Func<int, int> getPage = (pageNumber) =>
{
SimulateSlowHttpRequest();
Console.WriteLine(pageNumber);
return pageNumber;
};
var tasks = new List<Task<int>>();
for (int i = 1; i <= 5; i++)
{
task = Task.Run(() => getPage(i));
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
//...etc
}
public static void SimulateSlowHttpRequest()
{
var x = 1000000000;
var multiplier = new Random().Next(8, 16);
var y = x * multiplier;
for (int i = 0; i <= y; i++)
{
var result = i++;
}
}
I get the following output:
6
6
6
6
6
..or sometimes I might see a (e.g.) 3, but mostly 6s. If I change this line:
task = Task.Run(() => getPage(i));
to:
var j = i;
task = Task.Run(() => getPage(j));
then I get the expected output (numbers 1 to 5 on each line, albeit in a random order).
I suspect this is because:
a) the Tasks in the loop might start running at some undefined time after the for loop has finished, and
b) i
is being passed by reference to the Func, and the last value of it was 6
My question is why does it work with the above change above (i.e. making a local copy of i
) and what is a better design for the above? The above code is basically the same structure I am working with for a program which makes concurrent calls to a REST service to get data that is to be returned in one result.