C# Lambda 表达式和 foreach
循环线程安全
本文研究了在 C# lambda 表达式内的 foreach
循环中访问变量的线程安全性,重点关注 C# 版本之间的差异。
C# 5 之前的行为
在 5 之前的 C# 版本中,直接访问多线程上下文中使用的 lambda 表达式(例如,在 foreach
构造函数中)中 Thread
循环外部声明的变量是 不安全。 这是因为 foreach
循环的迭代器变量在所有迭代之间共享。 因此,多个线程可能会访问和修改同一变量,从而导致不可预测和不正确的结果。 竞争条件很有可能发生。
C# 5 及更高版本
从 C# 5 开始,编译器对 foreach
循环内迭代器的处理显着提高了线程安全性。 编译器现在可以有效地为每次迭代创建迭代器变量的新实例。 这意味着每个 lambda 表达式都会捕获变量的唯一副本,从而消除竞争条件的风险。 因此,在 C# 5 及更高版本中,这两种方法(使用在循环外部或内部声明的单个迭代器变量)通常被认为是线程安全.
说明性示例(C#5 之前的不安全行为)
以下代码片段突出显示了 C#5 之前版本中的不安全行为:
<code class="language-csharp">static void Main() { int[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; foreach (int i in data) { new Thread(() => Console.WriteLine(i)).Start(); } Console.ReadLine(); }</code>
运行此代码可能会产生 i
值顺序不正确的输出,这表明了竞争条件。每个线程捕获相同的 i
变量,并且当线程执行其 lambda 表达式时,其值可能会发生变化。
结论
虽然较旧的 C# 版本需要仔细处理 lambda 表达式中的 foreach
循环中的迭代器变量以确保线程安全,但 C# 5 及更高版本通过编译器优化缓解了此问题。 但是,注意潜在的并发问题仍然是一个好习惯,尤其是在处理 lambda 表达式中的共享资源时,无论 C# 版本如何。 在每次迭代中使用局部变量仍然是清晰度和可维护性的最佳实践。
以上是在 C# Lambda 表达式中的 Foreach 循环中访问变量是线程安全的吗?的详细内容。更多信息请关注PHP中文网其他相关文章!