C#多线程

时间:2015-04-22 14:06:40

标签: c# multithreading

我正在尝试学习如何在C#中使用多线程。我在this tutorial工作,它解释了使用lambda表达式传递参数。我制作了一个玩具程序来测试这个,但我对输出感到困惑。

这是我的代码:

using System;
using System.Threading;

namespace MultithreadingApplication
{
   class ThreadCreationProgram
   {
      public static void CallToChildThread(int id)
      {
         Console.WriteLine(string.Format("Child thread {0} starts", id));
      }

      static void Main(string[] args)
      {
        for (int i=0; i<10; i++)
        {
            Console.WriteLine(string.Format("i: {0}", i));
            Thread childThread = new Thread( () => CallToChildThread (i) );
             childThread.Start();
        }
      }
   }
}

这是输出:

i: 0
i: 1
Child thread 1 starts
i: 2
Child thread 2 starts
i: 3
Child thread 3 starts
i: 4
Child thread 4 starts
Child thread 5 starts
i: 5
i: 6
Child thread 6 starts
i: 7
i: 8
Child thread 7 starts
i: 9
Child thread 9 starts
Child thread 8 starts
Child thread 10 starts

子函数仅打印出传递的id的值。我预计这些范围从0到9,但CallToChildThread代替显示1到10.有人可以解释原因吗?

1 个答案:

答案 0 :(得分:2)

我刚刚运行该程序并得到以下结果:

i: 0
i: 1
i: 2
Child thread 2 starts
i: 3
Child thread 2 starts
Child thread 3 starts
i: 4
Child thread 4 starts
Child thread 4 starts
i: 5
i: 6
i: 7
Child thread 7 starts
Child thread 7 starts
i: 8
i: 9
Child thread 9 starts
Child thread 9 starts
Child thread 10 starts

这很好地演示了多线程的一个问题:共享变量。在这一行:

Thread childThread = new Thread( () => CallToChildThread (i) );

您将假设您创建了一个当前值为i的lambda。你没有。您使用引用创建一个lambda到i,即循环变量。只有当您的子线程到达CallToChildThread的开头(可能在稍后的某个时间发生)时,才会评估i的值并将其复制到局部变量id

修复很简单:

int _i = i;
Thread childThread = new Thread(() => CallToChildThread(_i));

这将产生0到9的子线程。