首頁 > 後端開發 > C++ > 為什麼 Foreach 迴圈和閉包需要在多執行緒 C# 程式碼中進行特殊處理?

為什麼 Foreach 迴圈和閉包需要在多執行緒 C# 程式碼中進行特殊處理?

Patricia Arquette
發布: 2025-01-22 07:17:13
原創
963 人瀏覽過

Why Do Foreach Loops and Closures Require Special Handling in Multithreaded C# Code?

了解多執行緒 C# 中的 foreach 迴圈與閉包

C# 中的多執行緒在使用 foreach 循環和閉包時會帶來複雜性。 當 foreach 迴圈內的閉包引用迴圈的迭代變數時,就會出現問題。

考慮這個例子:

<code class="language-csharp">var threads = new List<Thread>();
foreach (Foo f in ListOfFoo)
{      
    Thread thread = new Thread(() => f.DoSomething());
    threads.Add(thread);
    thread.Start();
}</code>
登入後複製

這裡,每個執行緒的閉包捕獲對單一 f 變數的引用。 隨著循環的進行,f 的值會發生變化,導致不可預測的結果 - 執行緒可能會對意外的 Foo 物件進行操作。

確保執行緒安全

為了避免這種情況,請在每次迭代中建立一個新的局部變數:

<code class="language-csharp">var threads = new List<Thread>();
foreach (Foo f in ListOfFoo)
{      
    Foo f2 = f; // Create a copy for each thread
    Thread thread = new Thread(() => f2.DoSomething());
    threads.Add(thread);
    thread.Start();
}</code>
登入後複製

現在,每個執行緒都有自己獨立的參考 (f2),確保在正確的 DoSomething() 實例上呼叫 Foo

C# 5 及更高版本

C# 5 及更高版本中的行為略有變化。 編譯器將 foreach 變數視為在循環範圍內有效聲明的變量,即使它出現在循環範圍之外。 因此,上面的兩個程式碼片段在 C# 5 及後續版本中都是線程安全的。 然而,為了清晰度和向後相容性,顯式副本仍然是良好的做法。

以上是為什麼 Foreach 迴圈和閉包需要在多執行緒 C# 程式碼中進行特殊處理?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板