在lambda中使用循环变量

时间:2014-02-24 15:40:38

标签: c# for-loop lambda

这种行为是在c#中定义的吗?

static void Main(string[] args)
{
    for (int i = 0; i < 10; i++)
    {
        Task.Run(() => Console.WriteLine("This is task " + i));
    }

    Console.ReadLine();
}

输出

This is task 10
This is task 10
This is task 10
This is task 10
This is task 10
This is task 10
This is task 10
This is task 10
This is task 10
This is task 10

我知道如何修复它,我知道它为什么会发生,但这是一种定义的行为吗?

1 个答案:

答案 0 :(得分:5)

不,它不是定义的行为。这是一种竞争条件,其中每个输出可以是任何值,从0到10,以任何顺序。它取决于相对于主程序执行生成的任务的时间;反过来,这在很大程度上取决于机器的多处理能力。如果某个任务碰巧被工作线程拾取并在循环完成之前执行了,那么您将获得在该时间点发生在循环计数器中的任何值。

你经常得到循环计数器的最终值的原因是主循环在计算上是微不足道的,并且在任何任务有机会运行之前完成。如果您想观察非确定性,请在循环中添加一个人工延迟:

for (int i = 0; i < 10; i++)
{
    Task.Factory.StartNew(() => Console.WriteLine("This is task " + i));
    Thread.SpinWait(20000);
}

英特尔酷睿i7上的示例输出:

This is task 2
This is task 3
This is task 3
This is task 3
This is task 4
This is task 5
This is task 7
This is task 8
This is task 9
This is task 8

如果您使用足够大的延迟,任务将有机会以直观预期的顺序运行,输出0, 1, 2, ..., 9