【问题标题】:c# Why does this for loop with a task.run prints more than 10 times? [duplicate]c#为什么这个for循环与task.run打印超过10次? [复制]
【发布时间】:2016-06-24 05:05:28
【问题描述】:

这里发生了什么?这个循环大部分时间只是打印这个:

10101010101010101010

有时是这样的:

51010101010101010101

当我调试它时,它会按顺序打印

0123456789

class Program
{
    static void Main (string[] args)
    {
        for ( int i = 0; i < 10; i++)
        {
            Task.Run(( ) => Console.Write(i));
        }
        Console.Read();
    }
}

【问题讨论】:

  • Lambda 捕获变量,而不是值。
  • lambda 捕获了 变量,这意味着所有任务都在尝试读取相同的值。他们中的一些人读取了5 的值,而一些人读取了最后一个值10

标签: c# task


【解决方案1】:

如果您安装了 ReSharper,它会在 i 下方显示一个小波浪线:

附注:

访问修改后的闭包

JetBrains site 给出了这样的解释:

这似乎是正确的,但实际上,只要单击任何按钮,就会使用 str 变量的最后一个值。这样做的原因是 foreach 展开到一个 while 循环中,但是迭代变量是在这个循环之外定义的。这意味着当您显示消息框时,str 的值可能已经迭代到字符串集合中的最后一个值。

(显然他们的示例使用的是字符串而不是 int)。

它在调试下“工作”,因为其他事情正在发生并且代码的执行与发布时不同。

解决办法是使用局部变量:

    for ( int i = 0; i < 10; i++)
    {
        int local = i;
        Task.Run(( ) => Console.Write(local));
    }

但即便如此,也不能保证按您期望的顺序执行。我刚刚对此进行了测试并得到了结果:

0436215897

所以每个值都被处理了,但顺序不确定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 2021-10-10
    相关资源
    最近更新 更多