C# 中的 foreach
变量与多线程闭包:安全吗?
在 C# 中使用 foreach
循环遍历集合时,理解迭代变量的作用域和行为至关重要,尤其是在多线程环境下。
以下代码片段探讨了在多线程中直接使用 foreach
变量作为闭包参数是否安全,以及是否需要为每次迭代创建局部副本。
C# 5 之前的版本
在 C# 5 之前的版本中,foreach
变量是在循环外部声明的。这意味着单个变量实例在所有迭代中共享。
考虑第一个代码片段:
<code class="language-csharp">foreach (Foo f in ListOfFoo) { Thread thread = new Thread(() => f.DoSomething()); threads.Add(thread); thread.Start(); }</code>
在此例中,f
变量在循环迭代期间创建的所有线程之间共享。这可能导致不可预测的结果,因为多个线程最终可能在 Foo
的不同实例上调用方法,或者多次调用同一实例上的方法。
为避免此类问题,建议在每次迭代中创建 f
变量的局部副本,如第二个代码片段所示:
<code class="language-csharp">foreach (Foo f in ListOfFoo) { Foo f2 = f; Thread thread = new Thread(() => f2.DoSomething()); threads.Add(thread); thread.Start(); }</code>
C# 5 及更高版本
C# 5 引入了显著的变化。在 C# 5 及更高版本中,foreach
变量在循环作用域内定义。这意味着每次迭代都有其自己的变量实例。
因此,两个代码片段变得等效且安全。每个线程现在在其闭包作用域内拥有自己的 f
实例,消除了混淆或不一致的风险。
以上是在 C# 多线程闭包中直接使用 `foreach` 变量安全吗?的详细内容。更多信息请关注PHP中文网其他相关文章!