Przejdź do treści stopki
Iron Academy Logo
Naucz się C#
Naucz się C#

Inne Kategorie

Łatwe Wartości Losowe Odpornie na Wątek w C# – Głęboka analiza z Timem Coreyem

Tim Corey
10m 27s

Generowanie liczb losowych to jedno z zadań, które napotyka każdy programista. Chociaż stworzenie prostego losowego numeru może wydawać się trywialne, zapewnienie bezpieczeństwa wątków w C#, zwłaszcza w środowiskach wielowątkowych, może być trudne. W swoim wideo "Easy Thread-Safe Random Values in C#", Tim Corey omawia, jak działają liczby losowe w C#, pułapki starszych metod i jak osiągnąć bezpieczeństwo wątków podczas pracy z wieloma wątkami.

W tym artykule śledzimy wyjaśnienia Tima, dostarczając szczegółowego spojrzenia na generowanie losowych liczb bezpiecznych wątkowo, najlepsze praktyki i powiązane techniki synchronizacji.

Introduction to Random Values and Thread Safety in C

Tim zaczyna od wskazania, że generowanie wartości losowych w C# jest na ogół proste. Jednak istnieją różne sposoby działania, a wybór zależy od tego, czy Twój kod będzie działał w jednym wątku lub wielu wątkach jednocześnie. Tim podkreśla, że to wideo jest zaprojektowane jako szybki, praktyczny przewodnik dla programistów, przedstawiając zarówno proste przykłady, jak i głębsze spojrzenie na bezpieczeństwo wątków.

Demonstruje swoje przykłady w aplikacji konsolowej używając Visual Studio 2026 wersja zapoznawcza z .NET 10, ale zapewnia widzów, że ten sam kod działa w Visual Studio 2022 i .NET 9. Dla tych, którzy chcą śledzić, Tim dostarcza kod źródłowy w opisie.

Traditional Random Number Generation in C

Tim zaczyna od pokazania klasycznego podejścia do generowania liczb losowych przy użyciu klasy Random. Tworzy dwa instancje, RNG1 i RNG2 oraz demonstruje generowanie losowych liczb całkowitych za pomocą funkcji 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 wyjaśnia, że uruchomienie tego kodu generuje różne liczby dla każdej instancji, ale ten kod nie jest bezpieczny wątkowo. W środowisku wielowątkowym, jeśli dwa wątki uzyskują dostęp do tej samej instancji Random, możesz otrzymać niespodziewane wartości lub duplikaty, ponieważ wewnętrzny stan obiektu Random może być otwierany jednocześnie.

Wskazuje, że jednym ze sposobów na zapewnienie bezpieczeństwa wątków jest użycie jednej Instancji Random na wątek. To ważne dla wątków roboczych, asynchronicznych metod albo w każdej sytuacji, w której wiele wątków może jednocześnie uruchamiać kod. Dzielenie tej samej instancji pomiędzy wątkami bez odpowiedniej synchronizacji może prowadzić do sytuacji wyścigu, niepoprawnych wartości albo nawet zakleszczeń, jeśli źle zarządzane.

Użycie nasion dla przewidywalnych liczb losowych

Tim potem demonstruje użycie nasienia. Nasiono to wartość startowa, która determinuje sekwencję generowanych liczb. Na przykład, użycie nasienia 25 dla obu RNG1 i RNG2:

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

Oba instancje produkują taką samą sekwencję liczb. Tim podkreśla, że to jest funkcja, nie błąd, i jest to użyteczne dla scenariuszy, w których wymagana jest powtarzalność. To może pomóc w testach jednostkowych lub debugowaniu programu wielowątkowego, gdy potrzebujesz powtórzyć sekwencję przypadkowych wartości pomiędzy dwoma lub więcej wątkami.

Liczby losowe bezpieczne wątkowo z Random.Shared

Tim wprowadza Random.Shared, nowoczesny, bezpieczny wątkowo sposób generowania liczb losowych. Inaczej niż w przypadku ręcznego tworzenia instancji, Random.Shared to statyczny, współdzielony zasób, który automatycznie obsługuje równoległy dostęp:

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

Przy takim podejściu nie musisz martwić się o blokady, statyczne konstruktory czy współdzielone zasoby. Wbudowane kolekcje bezpieczne wątkowo w .NET i instancja Random.Shared czynią go bezpiecznym do użycia w wielu wątkach jednocześnie.

Zalety Random.Shared

Tim przedstawia kilka korzyści z tego podejścia:

  • Nie wymaga instancjacji: Nie potrzebujesz oddzielnych instancji dla każdego wątku.

  • Bezpieczny wątkowo domyślnie: Bezpieczny do użycia w zadaniach równoległych lub wątkach roboczych.

  • Prosty API: Obsługuje liczby całkowite, dziesiętne, a nawet tasowanie tablic.

Wspomina jeden ograniczenie: nie możesz ustawić nasienia, co oznacza, że sekwencje nie są przewidywalne. Dla scenariuszy, w których potrzebny jest ten sam porządek liczb w wielu uruchomieniach, nadal powinieneś używać indywidualnych instancji z nasieniem.

Zapewnienie bezpieczeństwa wątków w złożonym kodzie

Chociaż Random.Shared wewnętrznie obsługuje bezpieczeństwo wątków, przykłady Tima pozwalają omówić ogólne techniki bezpieczeństwa wątków w C#. W bardziej złożonym kodzie lub środowiskach wielowątkowych, często trzeba poprawnie synchronizować, aby uniknąć sytuacji wyścigu i zapewnić integralność danych. Niektóre popularne techniki obejmują:

  • Instrukcja Lock: Zapobiega jednoczesnemu dostępowi wielu wątków do krytycznej sekcji.

  • Członkowie statyczni i statyczne konstruktory: Mogą być używane do bezpiecznego inicjowania zasobów współdzielonych.

  • Kolekcje bezpieczne wątkowo: Klasy takie jak ConcurrentQueue, ConcurrentStack i ConcurrentDictionary pozwalają na bezpieczny równoległy dostęp.

  • Wykluczanie wzajemne (Mutex/Monitor): Zapewnia, że tylko jeden wątek może jednocześnie wykonywać sekcję kodową.

Tim wyjaśnia, że w większości przypadków dla numerów losowych, Random.Shared usuwa potrzebę tych technik, ale w aplikacjach wielowątkowych z współdzielonymi zasobami, te metody są niezbędne, aby uniknąć zakleszczeń i niespodziewanych wartości.

Praktyczne wytyczne od Tim Corey

Tim dostarcza jasnych wskazówek, jak bezpiecznie używać liczb losowych w wielowątkowych aplikacjach:

  1. Użyj Random.Shared dla prostoty: Idealne, gdy po prostu potrzebujesz losowej wartości i liczy się wydajność.

  2. Użyj instancji z nasieniem dla powtarzalności: Konieczne, gdy śledzisz te same dane lub debugujesz w środowiskach wielowątkowych.

  3. Unikaj Random w kryptografii: Dla bezpieczeństwa, używaj bibliotek kryptograficznych.

  4. Zrozum podstawy bezpieczeństwa wątków: Wiedź, kiedy Twój kod jest w całości dostępny przez wiele wątków i implementuj synchronizację tylko wtedy, gdy jest to konieczne.

Uspokaja programistów, że Random.Shared działa nawet, gdy z wielu wątków wykonuje się miliony wywołań na milisekundę, a on efektywnie obsługuje równoległy dostęp.

Conclusion: Safe and Simple Random Numbers in C

Wideo Tima Coreya "video " pokazuje, że generowanie liczb losowych bezpiecznych wątkowo w C# jest łatwiejsze, niż się wielu programistom wydaje. Używając Random.Shared, można uniknąć wielu pułapek związanych z środowiskami wielowątkowymi. W przypadkach, gdy potrzebne są przewidywalne sekwencje, używanie poszczególnych instancji z nasieniem zapewnia niezawodne podejście.

Rozumienie bezpieczeństwa wątków, sekcji krytycznych i technik synchronizacji zapewnia, że kod pozostaje poprawny i dobrze działa w wielowątkowych aplikacjach. Podążając za wskazówkami Tima, deweloperzy mogą z pewnością pisać kod bezpieczny dla wątków dla wątków roboczych, asynchronicznych metod i zadań równoległych bez obaw o wyścigi, zakleszczenia lub nieoczekiwane wartości.

Hero Worlddot related to Łatwe Wartości Losowe Odpornie na Wątek w C# – Głęboka analiza z Timem Coreyem
Hero Affiliate related to Łatwe Wartości Losowe Odpornie na Wątek w C# – Głęboka analiza z Timem Coreyem

Zarabiaj więcej, dzieląc się tym, co kochasz

Tworzysz treści dla deweloperów pracujących z .NET, C#, Java, Python, czy Node.js? Zamień swoją wiedzę specjalistyczną na dodatkowy dochód!

Zespol wsparcia Iron

Jestesmy online 24 godziny, 5 dni w tygodniu.
Czat
Email
Zadzwon do mnie