令人困惑的线程行为

时间:2013-08-05 06:40:25

标签: c#

在C#中,如果我执行

for (int i = 0;i < 10;i++)
    new Thread(() => Console.Write(i)).Start();

我可能会得到0223557799,这很奇怪,因为我是一个int,我认为它应该在线程开始之前复制。

5 个答案:

答案 0 :(得分:2)

关闭是您的问题。

基本上,当你创建 lambda(在循环中)时,它不是抓取值,而是在需要时抓取它。计算机速度如此之快,以至于它发生时已经发生了变化。它无法通过整个循环,但它会经历一些循环。

这是一个修复:

for (int i = 0; i < 10; i++) 
{
    var n = i;
    new Thread(() => Console.Write(n)).Start();
}

答案 1 :(得分:1)

由于Start()立即返回,i++在线程有机会向控制台打印i之前发生。我相信解决方法是创建int的本地副本,然后打印:

for (int i = 0;i < 10;i++) {
    int j = i;
    new Thread(() => Console.Write(j)).Start();
}

答案 2 :(得分:1)

基本上发生了什么:

  1. 您想要启动一个打印i值的线程。

  2. 线程开始。

  3. 线程中运行的代码获取i的值。 请注意,i的值现在可以更改。

  4. 打印i的值。但无法保证获得合理的输出。

  5. 首先将i的值复制到另一个变量中,然后打印该值。其他答案提供了足够的样本代码。

答案 3 :(得分:0)

你的lambda将被翻译成方法和上下文类的集合,它将处理对i的引用。

答案 4 :(得分:0)

我会使用内置的.NET并行支持Task Parallelism

您不必担心管理它为您完成的线程。

将代码示例转换为Parallelism库。

Parallel.For(0, 10, (i, state) =>
{
    Console.WriteLine(i);
});