跳過到頁腳內容
Iron Academy Logo
學習 C#
學習 C#

其他分類

C# 中的簡易線程安全隨機值—Tim Corey 的深入探討

Tim Corey
10m 27s

生成隨機數是每個開發者都會遇到的任務之一。 雖然創建一個簡單的隨機值似乎很簡單,但在C#中確保線程安全,尤其在多線程環境中,可能會很棘手。 在他的視頻"Easy Thread-Safe Random Values in C#"中,Tim Corey 探討了在C#中隨機數的工作方式、舊方法的陷阱,以及如何在處理多線程時實現線程安全。

在這篇文章中,我們將遵循 Tim 的解釋,詳細介紹線程安全的隨機數生成、最佳實踐和相關同步技術。

Introduction to Random Values and Thread Safety in C

Tim 開始指出,在 C# 中生成隨機值通常是很簡單的。 然而,事情可以有不同的方法,而選擇取決於您的代碼是運行在一個線程中還是多個線程中同時進行。 Tim 強調這個視頻是為開發者設計的快速實用指南,同時提供簡單的示例和對於線程安全的更深入的見解。

他在使用 Visual Studio 2026 預覽版和 .NET 10 的控制台應用程序中演示的示例,但向觀眾保證,同樣的代碼在 Visual Studio 2022 和 .NET 9 中也能夠運行。對於想要跟隨的人,Tim 在描述中提供了源代碼。

Traditional Random Number Generation in C

Tim 開始展示使用 Random 類生成隨機數的經典方法。 他創建了兩個實例,RNG1 和 RNG2,並演示如何使用 Next() 生成隨機整數。

Random rng1 = new();
Random rng2 = new();

for(int i = 0; i < 10; i++)
{
    int output1 = rng1.Next(1, 101);
    int output2 = rng2.Next(1, 101);

    Console.WriteLine($"Random 1: {output1}, Random 2: {output2}");
}

Tim 解釋說運行這段代碼會為每個實例產生不同的數字,但這段代碼不是線程安全的。 在多線程環境中,如果兩個線程訪問同一個 Random 實例,可能會因為 Random 對象的內部狀態被同時訪問而導致值意外或重複。

他指出確保線程安全的一種方法是為每個線程使用一個 Random 實例。 這對於工作線程、異步方法或任何多個線程可能同時運行代碼的情況都很重要。 在沒有適當同步的情況下在多個線程間共享同一實例可能導致競態條件、錯誤的值,甚至如果管理不當會造成死鎖。

使用 Seed 來生成可預測的隨機數

然後,Tim 展示了種子的使用。 種子是一個決定生成的數字序列的初始值。 例如,對於 RNG1 和 RNG2 使用種子值25:

Random rng1 = new(25);
Random rng2 = new(25);

兩個實例都產生相同的數字序列。 Tim 強調這是一個特性,而不是一個漏洞,並在需要重現性的場景中很有用。 這可以幫助在單元測試或調試多線程程序時需要在多個線程中重現隨機值序列的情況。

使用 Random.Shared 來獲得線程安全的隨機數

Tim 介紹了 Random.Shared,這是一種生成線程安全隨機數的現代方法。 與手動創建實例不同,Random.Shared 是一個靜態的共享資源,能夠自動處理並發訪問:

int output1 = Random.Shared.Next();
int output2 = Random.Shared.Next();

使用這種方法,您不必擔心鎖、靜態構造函數或共享資源。 .NET 內建的線程安全集合和 Random.Shared 實例使得可以安全地並發使用多個線程。

Random.Shared 的優勢

Tim 解釋了這種方法的幾個好處:

  • 無需實例化:無需為每個線程分開實例。

  • 默認線程安全:可以安全地在並行任務或工作線程中使用。

  • 簡單的 API:支持整數、小數,甚至陣列洗牌。

他確實指出了一個限制:不能設置種子,這意味著序列不可預測。 在需要跨多次運行得到相同順序數字的場合,您應該仍然使用具有種子的個別實例。

確保複雜代碼中的線程安全

雖然 Random.Shared 內部處理了線程安全,但 Tim 的示例允許我們討論 C# 中的一般線程安全技術。 在更複雜的代碼或多線程環境中,您常常需要正確同步以避免競態條件並確保數據完整性。 一些常見技術包括:

  • Lock 語句:防止多個線程同時訪問臨界區。

  • 靜態成員和靜態構造函數:可以用來安全地初始化共享資源。

  • 線程安全集合:像 ConcurrentQueue、ConcurrentStack 和 ConcurrentDictionary 這樣的類允許安全的並發訪問。

  • 互斥(Mutex/Monitor):確保一次只有一個線程可以執行代碼段。

Tim 解釋在大多數情況下,對於隨機數,Random.Shared 避免了這些技術的需要,但在具有共享資源的多線程應用中,這些方法對於避免死鎖和意外值是至關重要的。

Tim Corey 的實用指導

Tim 提供了在多線程應用中安全地使用隨機數的明確指導:

  1. 使用 Random.Shared 以獲得簡單性:在您只需要隨機值和性能很重要時,這是理想的選擇。

  2. 使用具有種子的實例以獲得重現性:在追蹤相同數據或在多線程環境中進行除錯時是必要的。

  3. 在密碼學中避免使用 Random:為了安全,改用密碼學庫。

  4. 理解線程安全的基本知識:知道何時您的代碼被多線程訪問,以及在必要時僅實施同步。

他向開發者保證,即使每毫秒有數百萬次調用,Random.Shared 也能高效地處理並發訪問。

Conclusion: Safe and Simple Random Numbers in C

Tim Corey 的視頻展示了在 C# 中生成線程安全隨機數比許多開發者想象的要容易。使用 Random.Shared,可以避免許多與多線程環境相關的陷阱。 在需要可預測序列的情況下,使用具有種子的個別實例提供了一個可靠的方法。

理解線程安全、臨界區和同步技術確保您的代碼在多線程應用中保持正確並且性能良好。 遵循 Tim 的指導,開發者可以自信地為工作線程、異步方法和並行任務編寫線程安全的代碼,而不必擔心競態條件、死鎖或意外值。

Hero Worlddot related to C# 中的簡易線程安全隨機值—Tim Corey 的深入探討
Hero Affiliate related to C# 中的簡易線程安全隨機值—Tim Corey 的深入探討

通過分享您所愛的東西賺得更多

您是否在為使用.NET、C#、Java、Python或Node.js的開發者創建內容?將您的專業知識轉化為額外收入!

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我