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中文網其他相關文章!