嗨,在以下示例中,
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++;
}
}
我得到以下输出:
6
6
6
6
6
..有时我可能会看到(例如)3,但大多数是6s。如果我改变这一行:
task = Task.Run(() => getPage(i));
为:
var j = i;
task = Task.Run(() => getPage(j));
然后我得到预期的输出(每行数字1到5,虽然是随机顺序)。
我怀疑这是因为:
a)循环中的任务可能在for循环结束后的某个未定义时间开始运行,并且
b)i
通过引用传递给Func,它的最后一个值是6
我的问题是为什么它适用于上述变化(即制作i
的本地副本)以及上述更好的设计?上面的代码与我正在使用的程序基本相同,该程序对REST服务进行并发调用以获取将在一个结果中返回的数据。