同步處理原始物件概觀Overview of synchronization primitives

.NET 提供可用來同步對共用資源的存取或協調執行緒互動的一系列類型。.NET provides a range of types that you can use to synchronize access to a shared resource or coordinate thread interaction.

重要

使用相同同步處理原始物件執行個體來保護共用資源的存取。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 類別和輕量型同步處理類別WaitHandle class and lightweight synchronization types

衍生自 System.Threading.WaitHandle 類別的多個 .NET 同步處理原始物件,它能封裝原生作業系統同步處理控制代碼,並針對執行緒互動使用訊號機制。Multiple .NET synchronization primitives derive from the System.Threading.WaitHandle class, which encapsulates a native operating system synchronization handle and uses a signaling mechanism for thread interaction. 那些類別包括:Those classes include:

在 .NET Framework 中,由於 WaitHandle 是衍生自 System.MarshalByRefObject,因此這些類型可用來跨應用程式定義域界限同步處理執行緒的活動。In the .NET Framework, because WaitHandle derives from System.MarshalByRefObject, these types can be used to synchronize the activities of threads across application domain boundaries.

在 .NET Framework 與 .NET Core 中,這些類型有一部分可以代表具名系統同步處理控制代碼;其於整個作業系統中皆可見,並可以用來進行處理序間的同步處理:In the .NET Framework and .NET Core, 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:

  • Mutex (.NET Framework 與 .NET Core),Mutex (.NET Framework and .NET Core),
  • Semaphore (Windows 上的 .NET Framework 與 .NET Core),Semaphore (.NET Framework and .NET Core on Windows),
  • EventWaitHandle (Windows 上的 .NET Framework 與 .NET Core)。EventWaitHandle (.NET Framework and .NET Core on Windows).

如需詳細資訊,請參閱 WaitHandle API 參考。For more information, see the WaitHandle 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.

那些類型有一部分是衍生自 WaitHandle 之類型的替代方案。Some of those types are alternatives to the types derived from WaitHandle. 例如,SemaphoreSlimSemaphore 的輕量型替代方案。For example, SemaphoreSlim is a lightweight alternative to Semaphore.

對共用資源之存取的同步處理Synchronization of access to a shared resource

.NET 提供一系列的同步處理原始物件,以控制多個執行緒對共用資源的存取。.NET provides a range of synchronization primitives to control access to a shared resource by multiple threads.

Monitor 類別Monitor class

System.Threading.Monitor 類別會透過取得或釋放能識別共用資源之物件上的鎖定,來授與對該資源的互斥存取。The System.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. 其他執行緒將無法取得鎖定,且 Monitor.Enter 方法會等待直到釋放鎖定為止。Any other thread is blocked from acquiring the lock and the Monitor.Enter method waits until the lock is released. Enter 方法會取得已釋放的鎖定。The Enter method acquires a released lock. 您也可以使用 Monitor.TryEnter 方法來指定執行緒嘗試取得鎖定的時間長度。You can also use the Monitor.TryEnter method to specify the amount of time during which a thread attempts to acquire a lock. 由於 Monitor 類別具有執行緒同質性,因此取得鎖定的執行緒必須呼叫 Monitor.Exit 方法來釋放鎖定。Because the Monitor class has thread affinity, the thread that acquired a lock must release the lock by calling the Monitor.Exit method.

您可以使用 Monitor.WaitMonitor.PulseMonitor.PulseAll 方法來協調在相同物件上取得鎖定之執行緒的互動。You can coordinate the interaction of threads that acquire a lock on the same object by using the Monitor.Wait, Monitor.Pulse, and Monitor.PulseAll methods.

如需詳細資訊,請參閱 Monitor API 參考。For more information, see the Monitor API reference.

注意

請使用以 C# 撰寫的 lock 陳述式,以及使用 Visual Basic 撰寫的 SyncLock 陳述式來同步對共用資源的存取,而不要直接使用 MonitorUse the lock statement in C# and the SyncLock statement in Visual Basic to synchronize access to a shared resource instead of using the Monitor class directly. 那些陳述式是使用 EnterExit 方法來實作,並會使用 try…finally 區塊以確保所取得的鎖定一律會被釋放。Those statements are implemented by using the Enter and Exit methods and a try…finally block to ensure that the acquired lock is always released.

Mutex 類別Mutex class

System.Threading.Mutex 類別,它和 Monitor 相同,能授與對共用資源的獨佔存取權。The System.Threading.Mutex class, like Monitor, grants exclusive access to a shared resource. 使用其中一個 Mutex.WaitOne 方法多載來要求 Mutex 的擁有權。Use one of the Mutex.WaitOne method overloads to request the ownership of a mutex. Monitor 類似,Mutex 具有執行緒同質性,且取得 Mutex 的執行緒必須呼叫 Mutex.ReleaseMutex 方法來釋放它。Like Monitor, Mutex has thread affinity and the thread that acquired a mutex must release it by calling the Mutex.ReleaseMutex method.

Monitor 不同,Mutex 類別可以用於處理序間的同步處理。Unlike Monitor, the Mutex class can be used for inter-process synchronization. 若要這麼做,請使用具名 Mutex,這能使其於整個作業系統中皆可見。To do that, use a named mutex, which is visible throughout the operating system. 若要建立具名 Mutex 執行個體,請使用能指定名稱的 Mutex 建構函式To create a named mutex instance, use a Mutex constructor that specifies a name. 您也可以呼叫 Mutex.OpenExisting 方法來開啟現有的具名系統 Mutex。You also can call the Mutex.OpenExisting method to open an existing named system mutex.

如需詳細資訊,請參閱 Mutex 文章與 Mutex API 參考文件。For more information, see the Mutexes article and the Mutex API reference.

SpinLock 結構SpinLock structure

System.Threading.SpinLock 結構與 Monitor 類似,能根據鎖定的可用性授與對共用資源的獨佔存取。The System.Threading.SpinLock structure, like Monitor, grants exclusive access to a shared resource based on the availability of a lock. SpinLock 嘗試取得不可用的鎖定時,它會在迴圈中等候並重複檢查,直到該鎖定變得可用為止。When SpinLock attempts to acquire a lock that is unavailable, it waits in a loop, repeatedly checking until the lock becomes available.

如需使用微調鎖定之優缺點的詳細資訊,請參閱 SpinLock 文章與 SpinLock API 參考。For more information about the benefits and drawbacks of using spin lock, see the SpinLock article and the SpinLock API reference.

ReaderWriterLockSlim 類別ReaderWriterLockSlim class

System.Threading.ReaderWriterLockSlim 類別會授與對共用資源進行寫入的獨佔存取權,並允許多個執行緒同時存取該資源以進行讀取。The System.Threading.ReaderWriterLockSlim class grants exclusive access to a shared resource for writing and allows multiple threads to access the resource simultaneously for reading. 您應該使用 ReaderWriterLockSlim 來同步對支援安全執行緒讀取作業,但需要獨佔存取以執行寫入作業之共用資料結構的存取。You might want to use ReaderWriterLockSlim to synchronize access to a shared data structure that supports thread-safe read operations, but requires exclusive access to perform write operation. 當執行緒要求獨佔存取權 (例如,透過呼叫 ReaderWriterLockSlim.EnterWriteLock 方法) 時,後續的讀取器和寫入器要求會封鎖直到所有現有讀取器都結束鎖定,且寫入器已進入並離開鎖定為止。When a thread requests exclusive access (for example, by calling the ReaderWriterLockSlim.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.

如需詳細資訊,請參閱 ReaderWriterLockSlim API 參考。For more information, see the ReaderWriterLockSlim API reference.

旗號與 SemaphoreSlim 類別Semaphore and SemaphoreSlim classes

System.Threading.SemaphoreSystem.Threading.SemaphoreSlim 類別能限制可以同時存取共用資源或資源集區的執行緒數目。The System.Threading.Semaphore and System.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.

SemaphoreSlimSemaphore 的輕量型替代方案,並僅可用於在單一處理序界限內進行同步處理。SemaphoreSlim is a lightweight alternative to Semaphore and can be used only for synchronization within a single process boundary.

在 Windows 上,您可以使用 Semaphore 以進行處理序間的同步處理。On Windows, you can use Semaphore for the inter-process synchronization. 若要這麼做,請使用其中一個能指定名稱的旗號建構函式Semaphore.OpenExisting 方法,建立代表具名系統旗號的 Semaphore 執行個體。To do that, create a Semaphore instance that represents a named system semaphore by using one of the Semaphore constructors that specifies a name or the Semaphore.OpenExisting method. SemaphoreSlim 不支援具名系統旗號。SemaphoreSlim doesn't support named system semaphores.

如需詳細資訊,請參閱旗號與 SemaphoreSlim 文章,以及 SemaphoreSemaphoreSlim API 參考。For more information, see the Semaphore and SemaphoreSlim article and the Semaphore or SemaphoreSlim 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. 例如,如果執行緒 A 呼叫執行緒 B 的 Thread.Join 方法,在執行緒 B 完成之前,執行緒 A 將會被封鎖。For example, if thread A calls the Thread.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.

此節描述由 .NET 提供的其他訊號處理建構。This section describes additional signaling constructs provided by .NET.

EventWaitHandle、AutoResetEvent、ManualResetEvent 與 ManualResetEventSlim 類別EventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim classes

System.Threading.EventWaitHandle 類別代表執行緒同步處理事件。The System.Threading.EventWaitHandle class represents a thread synchronization event.

同步處理事件可以處於未收到訊號或已收到訊號的狀態。A synchronization event can be either in an unsignaled or signaled state. 當事件的狀態為未收到訊號時,呼叫該事件之 WaitOne 多載的執行緒會被封鎖,直到事件收到訊號為止。When the state of an event is unsignaled, a thread that calls the event's WaitOne overload is blocked until an event is signaled. EventWaitHandle.Set 方法會將事件的狀態設定為已收到訊號。The EventWaitHandle.Set method sets the state of an event to signaled.

已收到訊號之 EventWaitHandle 的行為會取決於其重設模式:The behavior of an EventWaitHandle that has been signaled depends on its reset mode:

在 Windows 上,您可以使用 EventWaitHandle 以進行處理序間的同步處理。On Windows, you can use EventWaitHandle for the inter-process synchronization. 若要這麼做,請使用其中一個能指定名稱的 EventWaitHandle 建構函式EventWaitHandle.OpenExisting 方法,建立代表具名系統同步處理事件的 EventWaitHandle 執行個體。To do that, create a EventWaitHandle instance that represents a named system synchronization event by using one of the EventWaitHandle constructors that specifies a name or the EventWaitHandle.OpenExisting method.

如需詳細資訊,請參閱 EventWaitHandle 文章。For more information, see the EventWaitHandle article. 如需 API 參考,請參閱 EventWaitHandleAutoResetEventManualResetEventManualResetEventSlimFor the API reference, see EventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim.

CountdownEvent 類別CountdownEvent class

System.Threading.CountdownEvent 類別代表會在計數為零時被設定的事件。The System.Threading.CountdownEvent class represents an event that becomes set when its count is zero. CountdownEvent.CurrentCount 大於零時,呼叫 CountdownEvent.Wait 的執行緒將會被封鎖。While CountdownEvent.CurrentCount is greater than zero, a thread that calls CountdownEvent.Wait is blocked. 呼叫 CountdownEvent.Signal 來使事件的計數遞減。Call CountdownEvent.Signal to decrement an event's count.

與可透過來自單一執行緒的訊號將多個執行緒解除封鎖的 ManualResetEventManualResetEventSlim 相反,您可以使用 CountdownEvent 以透過來自多個執行緒的訊號,將一或多個執行緒解除封鎖。In contrast to ManualResetEvent or ManualResetEventSlim, which you can use to unblock multiple threads with a signal from one thread, you can use CountdownEvent to unblock one or more threads with signals from multiple threads.

如需詳細資訊,請參閱 CountdownEvent 文章與 CountdownEvent API 參考。For more information, see the CountdownEvent article and the CountdownEvent API reference.

Barrier 類別Barrier class

System.Threading.Barrier 類別代表執行緒執行屏障。The System.Threading.Barrier class represents a thread execution barrier. 呼叫 Barrier.SignalAndWait 方法的執行緒會發出其已抵達屏障的訊號,並會持續等候,直到其他參與者執行緒也抵達屏障為止。A thread that calls the Barrier.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.

當有一或多個執行緒需要取得其他執行緒的結果以繼續至下個運算階段時,您可以使用 BarrierYou might use Barrier when one or more threads require the results of other threads before proceeding to the next computation phase.

如需詳細資訊,請參閱屏障文章與 Barrier API 參考。For more information, see the Barrier article and the Barrier API reference.

Interlocked 類別Interlocked class

System.Threading.Interlocked 類別可提供能針對變數執行簡易不可部分完成之作業的靜態方法。The System.Threading.Interlocked class provides static methods that perform simple atomic operations on a variable. 那些不可部分完成的作業包括對 64 位元整數值的相加、遞增和遞減、根據比較的交換和條件式交換,以及讀取作業。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.

如需詳細資訊,請參閱 Interlocked API 參考。For more information, see the Interlocked API reference.

SpinWait 結構SpinWait structure

System.Threading.SpinWait 結構能提供微調式等候的支援。The System.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. 使用 SpinWait,您可以指定在等待時旋轉一小段時間,並且只有在指定的時間內未符合條件時放棄 (例如,藉由等待或睡眠)。By using SpinWait, 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.

如需詳細資訊,請參閱 SpinWait 文章與 SpinWait API 參考。For more information, see the SpinWait article and the SpinWait API reference.

另請參閱See also