使用Lambda表达式将数据传递给线程

时间:2013-01-25 08:41:01

标签: c# multithreading

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

正如预期的那样,上述代码的输出是非确定性的,因为i变量指的是整个循环生命周期中的相同内存位置。因此,每个线程在一个变量上调用Console.Write,该变量的值可能会在运行时发生变化

然而,

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

也提供非确定性输出!我认为变量temp是每个循环迭代的局部变量。因此,每个线程捕获一个不同的内存位置,应该有np问题。

4 个答案:

答案 0 :(得分:2)

你的程序应该有10个lambda,每个lambdas写一个从0到9的数字到控制台。但是,不能保证线程按顺序执行。

答案 1 :(得分:2)

  

还提供非确定性输出!

不,不是。我已经检查过你的第一个代码(有重复的数字)十次和第二次(没有)。

所以一切正常。就像它应该的那样。

答案 2 :(得分:1)

第二个代码段应该是确定性的,因为每个线程最终都会写出它的temp,并且它们的所有临时值都会有所不同。

但是,它不保证线程将按其创建顺序安排执行。你会看到所有可能的临时数,但不一定按升序排列。

答案 3 :(得分:1)

以下是OP正确且两段代码都不正确的证明。

还有一个证据解决方案。

但是需要注意'非确定性'意味着线程接收错误的参数订单将从不保证。

下面的代码检查了第二段OP代码并证明它正在按预期工作..

我正在存储该对(线程标识,参数)然后将其打印以与线程输出进行比较以证明对没有被更改。我还添加了几百毫秒的随机睡眠,因此for index在那些时候应该明显改变。

        Dictionary<int, int> hash = new Dictionary<int, int>();
        Random r = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < 10; i++)
        {
            int temp = i;
            var th = new Thread(() =>
            {
                Thread.Sleep(r.Next(9) * 100);
                Console.WriteLine("{0} {1}", 
                    Thread.CurrentThread.GetHashCode(), temp);
            });

            hash.Add(th.GetHashCode(), temp);

            th.Start();
        }

        Thread.Sleep(1000);
        Console.WriteLine();

        foreach (var kvp in hash)
            Console.WriteLine("{0} {1}", kvp.Key, kvp.Value);