使用 Lambda 表达式将数据传递到线程
本文关键字:线程 数据 Lambda 表达式 使用 | 更新日期: 2023-09-27 17:56:11
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 问题。
您的程序应该有 10 个 lambda,每个 lambda 将 0 到 9 之间的一个数字写入控制台。 但是,不能保证线程将按顺序执行。
也给出了非确定性的输出!
不,不是。我已经检查了十次您的第一个代码(有重复的数字)和第二个代码(没有)。
所以一切都很好。正如它应该的那样。
第二个代码片段应该是确定性的,因为每个线程最终都会写入其temp
,并且它们的所有温度都会不同。
但是,它不保证线程将按其创建顺序计划执行。您将看到所有可能的临时工,但不一定按升序排列。
这是OP是正确的证据,他的两段代码都是不正确的。
还有一个有证据的解决方案。
但是需要注意的是,"非确定性"意味着线程接收错误的参数。订单将永远无法保证。
下面的代码检查了 OP 代码的第二段,并演示了它是否按预期工作。
我正在存储对(线程标识、参数),然后将其打印出来与线程输出进行比较,以证明对没有改变。我还添加了几百毫秒的随机睡眠,因此 for 索引应该在这些时候明显改变。
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);