This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can trysigning in orchanging directories.
Access to this page requires authorization. You can trychanging directories.
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Provides a mechanism for achieving mutual exclusion in regions of code between different threads.
public ref class Lock sealed
public sealed class Lock
type Lock = class
Public NotInheritable Class Lock
TheLock class can be used to define regions of code that require mutually exclusive access between threads of a process, commonly called critical sections, to prevent concurrent accesses to a resource. ALock
can be entered and exited, where the region of code between the enter and exit is a critical section associated with the lock. A thread that enters a lock is said to hold or own the lock until it exits the lock. At most one thread can hold a lock at any given time. A thread can hold multiple locks. A thread can enter a lock multiple times before exiting it, such as recursively. A thread that can't enter a lock immediately can wait until the lock can be entered or until a specified timeout expires.
When using theEnter orTryEnter methods to enter a lock:
try/finally
block.async
method, ensure that there is noawait
between the enter and exit. Locks are held by threads and the code following anawait
might run on a different thread.It is recommended to use theEnterScope method with a language construct that automatically disposes the returnedLock.Scope such as the C#using
keyword, or to use the C#lock
keyword, as these ensure that the lock is exited in exceptional cases. These patterns might also have performance benefits over usingEnter/TryEnter
andExit
. The following code fragment illustrates various patterns for entering and exiting a lock.
public sealed class ExampleDataStructure{ private readonly Lock _lockObj = new(); public void Modify() { lock (_lockObj) { // Critical section associated with _lockObj } using (_lockObj.EnterScope()) { // Critical section associated with _lockObj } _lockObj.Enter(); try { // Critical section associated with _lockObj } finally { _lockObj.Exit(); } if (_lockObj.TryEnter()) { try { // Critical section associated with _lockObj } finally { _lockObj.Exit(); } } }}
When using the C#lock
keyword or similar to enter and exit a lock, the type of the expression must be preciselySystem.Threading.Lock
. If the type of the expression is anything else, such asObject
or a generic type likeT
, a different implementation that is not interchangeable can be used instead (such asMonitor). For more information, see the relevantcompiler speclet.
Interrupt can interrupt threads that are waiting to enter a lock. On Windows STA threads, waits for locks allow message pumping that can run other code on the same thread during a wait. Some features of the waits can be overridden by a customSynchronizationContext.
Note
A thread that enters a lock, including multiple times such as recursively, must exit the lock the same number of times to fully exit the lock and allow other threads to enter the lock. If a thread exits while holding aLock
, the behavior of theLock
becomes undefined.
Caution
If, on a code path, a thread might enter multiple locks before exiting them, ensure that all code paths that might enter any two of those locks on the same thread enter them in the same order. Otherwise, it could lead to deadlocks. For example, consider that on one code path threadT1
enters lockL1
then lockL2
before exiting both, and on another code path threadT2
enters both locks in the inverse order. In that scenario, it would be possible for the following order of events to occur:T1
entersL1
,T2
entersL2
,T1
tries to enterL2
and waits,T2
tries to enterL1
and waits. There's a deadlock betweenT1
andT2
that can't be resolved, and any other threads that try to enter either lock in the future will also hang.
Lock() | Initializes a new instance of theLock class. |
IsHeldByCurrentThread | Gets a value that indicates whether the lock is held by the current thread. |
Enter() | Enters the lock, waiting if necessary until the lock can be entered. |
EnterScope() | Enters the lock, waiting if necessary until the lock can be entered. |
Equals(Object) | Determines whether the specified object is equal to the current object. (Inherited fromObject) |
Exit() | Exits the lock. |
GetHashCode() | Serves as the default hash function. (Inherited fromObject) |
GetType() | Gets theType of the current instance. (Inherited fromObject) |
MemberwiseClone() | Creates a shallow copy of the currentObject. (Inherited fromObject) |
ToString() | Returns a string that represents the current object. (Inherited fromObject) |
TryEnter() | Tries to enter the lock without waiting. |
TryEnter(Int32) | Tries to enter the lock, waiting if necessary for the specified number of milliseconds until the lock can be entered. |
TryEnter(TimeSpan) | Tries to enter the lock, waiting if necessary until the lock can be entered or until the specified timeout expires. |
Was this page helpful?
Was this page helpful?