C# 为什么这个任务生成循环从未停止过?
非常简单的场景。我运行一个紧密的循环,在每次迭代中生成任务。(不要问为什么。)C# 为什么这个任务生成循环从未停止过?,c#,task,C#,Task,非常简单的场景。我运行一个紧密的循环,在每次迭代中生成任务。(不要问为什么。) static void Main(字符串[]args) { 对于(int i=0;iWriteHelloAsync(i)); Console.ReadLine(); } 静态任务WriteHelloAsync(intx) { Console.WriteLine($“Hello{x}!”); 返回Task.CompletedTask; } 我可以在控制台中看到它以增量方式写入迭代编号。然而,当它达到100万的目标时,
static void Main(字符串[]args)
{
对于(int i=0;i<1000*1000;i++)
Task.Run(()=>WriteHelloAsync(i));
Console.ReadLine();
}
静态任务WriteHelloAsync(intx)
{
Console.WriteLine($“Hello{x}!”);
返回Task.CompletedTask;
}
我可以在控制台中看到它以增量方式写入迭代编号。然而,当它达到100万的目标时,它只是继续前进
但是为什么呢?这就是问题所在
你的循环停止在一百万
当它停在一百万之后,您会对WriteHelloAsync(i)
进行大量调用
您正在将i
传递给所有人。传递给Task.Run()
的lambda没有创建一个新的i
副本,该副本保存了i
在调用Task.Run()时的值。它们都有相同的i
,其值在循环结束之前一直在变化
在我这里的机器上,我看到的第一个数字是六位数,这意味着这是任务第一次真正调用WriteHelloAsync()
时的I
值。很快,它就开始做你所看到的事情
试试这个:
static void Main(string[] args)
{
for (int i = 0; i < 1000 * 1000; i++)
{
// The scope of j is limited to the loop block.
// For each new iteration, there is a new j.
var j = i;
Task.Run(() => WriteHelloAsync(j));
}
Console.ReadLine();
}
这是最新的
你的循环停止在一百万
当它停在一百万之后,您会对WriteHelloAsync(i)
进行大量调用
您正在将i
传递给所有人。传递给Task.Run()
的lambda没有创建一个新的i
副本,该副本保存了i
在调用Task.Run()时的值。它们都有相同的i
,其值在循环结束之前一直在变化
在我这里的机器上,我看到的第一个数字是六位数,这意味着这是任务第一次真正调用WriteHelloAsync()
时的I
值。很快,它就开始做你所看到的事情
试试这个:
static void Main(string[] args)
{
for (int i = 0; i < 1000 * 1000; i++)
{
// The scope of j is limited to the loop block.
// For each new iteration, there is a new j.
var j = i;
Task.Run(() => WriteHelloAsync(j));
}
Console.ReadLine();
}
闭包很神奇。你能提到决定变量为什么被重用的机制吗?它是一个闭包。我不明白。就在那里。它是i
。有一个i
。我以为我已经掌握了闭包。总是感激能学到新东西@EdPlunkett我看到答案的评论中解释了这一点。它在VS2012中已修复,但仅在使用foreach
时才修复<代码>for
循环仍将显示此行为。@gigidang!现在我正在学习新的东西!闭包很神奇。你能提到决定变量为什么被重用的机制吗?它是一个闭包。我不明白。就在那里。它是i
。有一个i
。我以为我已经掌握了闭包。总是感激能学到新东西@EdPlunkett我看到答案的评论中解释了这一点。它在VS2012中已修复,但仅在使用foreach
时才修复<代码>for
循环仍将显示此行为。@gigidang!现在我正在学习新的东西!这是另一个副本:这是另一个副本:
foreach (var i in Enumerable.Range(0, 1000 * 1000))
{
Task.Run(() => WriteHelloAsync(i));
}