Movatterモバイル変換


[0]ホーム

URL:


Skip to main content

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft EdgeMore info about Internet Explorer and Microsoft Edge
Table of contentsExit editor mode

Overview of synchronization primitives

Feedback

In this article

.NET provides a range of types that you can use to synchronize access to a shared resource or coordinate thread interaction.

Important

Use the same synchronization primitive instance to protect access of a shared resource. If you use different synchronization primitive instances to protect the same resource, you'll circumvent the protection provided by a synchronization primitive.

WaitHandle class and lightweight synchronization types

Multiple .NET synchronization primitives derive from theSystem.Threading.WaitHandle class, which encapsulates a native operating system synchronization handle and uses a signaling mechanism for thread interaction. Those classes include:

In .NET Framework, becauseWaitHandle derives fromSystem.MarshalByRefObject, these types can be used to synchronize the activities of threads across application domain boundaries.

In .NET Framework, .NET Core, and .NET 5+, some of these types can represent named system synchronization handles, which are visible throughout the operating system and can be used for the inter-process synchronization:

For more information, see theWaitHandle API reference.

Lightweight synchronization types don't rely on underlying operating system handles and typically provide better performance. However, they cannot be used for the inter-process synchronization. Use those types for thread synchronization within one application.

Some of those types are alternatives to the types derived fromWaitHandle. For example,SemaphoreSlim is a lightweight alternative toSemaphore.

Synchronization of access to a shared resource

.NET provides a range of synchronization primitives to control access to a shared resource by multiple threads.

Monitor class

TheSystem.Threading.Monitor class grants mutually exclusive access to a shared resource by acquiring or releasing a lock on the object that identifies the resource. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and theMonitor.Enter method waits until the lock is released. TheEnter method acquires a released lock. You can also use theMonitor.TryEnter method to specify the amount of time during which a thread attempts to acquire a lock. Because theMonitor class has thread affinity, the thread that acquired a lock must release the lock by calling theMonitor.Exit method.

You can coordinate the interaction of threads that acquire a lock on the same object by using theMonitor.Wait,Monitor.Pulse, andMonitor.PulseAll methods.

For more information, see theMonitor API reference.

Note

Use thelock statement in C# and theSyncLock statement in Visual Basic to synchronize access to a shared resource instead of using theMonitor class directly. Those statements are implemented by using theEnter andExit methods and atry…finally block to ensure that the acquired lock is always released.

Mutex class

TheSystem.Threading.Mutex class, likeMonitor, grants exclusive access to a shared resource. Use one of theMutex.WaitOne method overloads to request the ownership of a mutex. LikeMonitor,Mutex has thread affinity and the thread that acquired a mutex must release it by calling theMutex.ReleaseMutex method.

UnlikeMonitor, theMutex class can be used for inter-process synchronization. To do that, use a named mutex, which is visible throughout the operating system. To create a named mutex instance, use aMutex constructor that specifies a name. You can also call theMutex.OpenExisting method to open an existing named system mutex.

For more information, see theMutexes article and theMutex API reference.

SpinLock structure

TheSystem.Threading.SpinLock structure, likeMonitor, grants exclusive access to a shared resource based on the availability of a lock. WhenSpinLock attempts to acquire a lock that is unavailable, it waits in a loop, repeatedly checking until the lock becomes available.

For more information about the benefits and drawbacks of using spin lock, see theSpinLock article and theSpinLock API reference.

ReaderWriterLockSlim class

TheSystem.Threading.ReaderWriterLockSlim class grants exclusive access to a shared resource for writing and allows multiple threads to access the resource simultaneously for reading. You might want to useReaderWriterLockSlim to synchronize access to a shared data structure that supports thread-safe read operations, but requires exclusive access to perform write operation. When a thread requests exclusive access (for example, by calling theReaderWriterLockSlim.EnterWriteLock method), subsequent reader and writer requests block until all existing readers have exited the lock, and the writer has entered and exited the lock.

For more information, see theReaderWriterLockSlim API reference.

Semaphore and SemaphoreSlim classes

TheSystem.Threading.Semaphore andSystem.Threading.SemaphoreSlim classes limit the number of threads that can access a shared resource or a pool of resources concurrently. Additional threads that request the resource wait until any thread releases the semaphore. Because the semaphore doesn't have thread affinity, a thread can acquire the semaphore and another one can release it.

SemaphoreSlim is a lightweight alternative toSemaphore and can be used only for synchronization within a single process boundary.

On Windows, you can useSemaphore for the inter-process synchronization. To do that, create aSemaphore instance that represents a named system semaphore by using one of theSemaphore constructors that specifies a name or theSemaphore.OpenExisting method.SemaphoreSlim doesn't support named system semaphores.

For more information, see theSemaphore and SemaphoreSlim article and theSemaphore orSemaphoreSlim API reference.

Thread interaction, or signaling

Thread interaction (or thread signaling) means that a thread must wait for notification, or a signal, from one or more threads in order to proceed. For example, if thread A calls theThread.Join method of thread B, thread A is blocked until thread B completes. The synchronization primitives described in the preceding section provide a different mechanism for signaling: by releasing a lock, a thread notifies another thread that it can proceed by acquiring the lock.

This section describes additional signaling constructs provided by .NET.

EventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim classes

TheSystem.Threading.EventWaitHandle class represents a thread synchronization event.

A synchronization event can be either in an unsignaled or signaled state. When the state of an event is unsignaled, a thread that calls the event'sWaitOne overload is blocked until an event is signaled. TheEventWaitHandle.Set method sets the state of an event to signaled.

The behavior of anEventWaitHandle that has been signaled depends on its reset mode:

On Windows, you can useEventWaitHandle for the inter-process synchronization. To do that, create anEventWaitHandle instance that represents a named system synchronization event by using one of theEventWaitHandle constructors that specifies a name or theEventWaitHandle.OpenExisting method.

For more information, see theEventWaitHandle article. For the API reference, seeEventWaitHandle,AutoResetEvent,ManualResetEvent, andManualResetEventSlim.

CountdownEvent class

TheSystem.Threading.CountdownEvent class represents an event that becomes set when its count is zero. WhileCountdownEvent.CurrentCount is greater than zero, a thread that callsCountdownEvent.Wait is blocked. CallCountdownEvent.Signal to decrement an event's count.

In contrast toManualResetEvent orManualResetEventSlim, which you can use to unblock multiple threads with a signal from one thread, you can useCountdownEvent to unblock one or more threads with signals from multiple threads.

For more information, see theCountdownEvent article and theCountdownEvent API reference.

Barrier class

TheSystem.Threading.Barrier class represents a thread execution barrier. A thread that calls theBarrier.SignalAndWait method signals that it reached the barrier and waits until other participant threads reach the barrier. When all participant threads reach the barrier, they proceed and the barrier is reset and can be used again.

You might useBarrier when one or more threads require the results of other threads before proceeding to the next computation phase.

For more information, see theBarrier article and theBarrier API reference.

Interlocked class

TheSystem.Threading.Interlocked class provides static methods that perform simple atomic operations on a variable. Those atomic operations include addition, increment and decrement, exchange and conditional exchange that depends on a comparison, and read operation of a 64-bit integer value.

For more information, see theInterlocked API reference.

SpinWait structure

TheSystem.Threading.SpinWait structure provides support for spin-based waiting. You might want to use it when a thread has to wait for an event to be signaled or a condition to be met, but when the actual wait time is expected to be less than the waiting time required by using a wait handle or by otherwise blocking the thread. By usingSpinWait, you can specify a short period of time to spin while waiting, and then yield (for example, by waiting or sleeping) only if the condition was not met in the specified time.

For more information, see theSpinWait article and theSpinWait API reference.

See also

Collaborate with us on GitHub
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, seeour contributor guide.

Feedback

Was this page helpful?

YesNoNo

Need help with this topic?

Want to try using Ask Learn to clarify or guide you through this topic?

Suggest a fix?

  • Last updated on

In this article

Was this page helpful?

YesNo
NoNeed help with this topic?

Want to try using Ask Learn to clarify or guide you through this topic?

Suggest a fix?