首頁 >後端開發 >C++ >在 C# Lambda 表達式中的 Foreach 循環中存取變數是線程安全的嗎?

在 C# Lambda 表達式中的 Foreach 循環中存取變數是線程安全的嗎?

DDD
DDD原創
2025-01-22 07:11:08287瀏覽

Is Accessing Variables in Foreach Loops Within C# Lambda Expressions Thread-Safe?

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

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn