Synchronization primitives and concurrent collections
On trails:NETCONCstep 7/11
When multiple threads access shared resources, synchronization is necessary to prevent data corruption and to ensure orderly execution. .NET provides several synchronization primitives:
lockstatement (syntactic sugar forSystem.Threading.Monitor) gives exclusive access to a block of code for a given object, so only one thread can execute it at a time.SemaphoreSlimlimits the number of threads that can access a resource, or a pool of resources, concurrently.Mutexis similar tolock, but can be used for inter-process synchronization.Monitor.Wait(),Monitor.Pulse()andMonitor.PulseAll()are used for more complex coordination patterns, where threads need to wait for specific conditions to be met.ReaderWriterLockSlimallows multiple threads to read a resource concurrently, but gives exclusive access to a single thread for writing. It’s useful for read-heavy, write-infrequent scenarios.
Concurrent collections
The collections in System.Collections.Concurrent, for example ConcurrentDictionary<TKey, TValue>, ConcurrentQueue<T> and ConcurrentBag<T>, are designed to be thread-safe for common operations. That reduces the need for manual locking.
Without them, shared data is open to race conditionsRace conditionsThe result depends on the order in which threads happen to run.Opens in a new tab, and locks taken in the wrong order cause deadlocksDeadlocksTwo or more threads wait on each other forever.Opens in a new tab.