Enum ReentrantSemaphore.ReentrancyMode
- Namespace
- Microsoft.VisualStudio.Threading
- Assembly
- Microsoft.VisualStudio.Threading.dll
Describes ways the ReentrantSemaphore may behave when a semaphore request is made in a context that is already in the semaphore.
public enum ReentrantSemaphore.ReentrancyMode
Fields
Freeform = 3
A request made by a caller that is already in the semaphore is immediately executed, and shares the same semaphore slot with its parent. The slot is only released when all requests have exited, which may be in any order.
This is the most permissive, but has the highest risk that leaked semaphore access will remain undetected. Leaked semaphore access is a condition where code is inappropriately considered parented to another semaphore holder, leading to it being allowed to run code within the semaphore, potentially in parallel with the actual semaphore holder.
NotAllowed = 0
Reject all requests when the caller has already entered the semaphore (and not yet exited) by throwing an InvalidOperationException.
When reentrancy is not expected this is the recommended mode as it will prevent deadlocks when unexpected reentrancy is detected.
NotRecognized = 1
Each request occupies a unique slot in the semaphore. Reentrancy is not recognized and may lead to deadlocks if the reentrancy level exceeds the count on the semaphore. This resembles the behavior of the AsyncSemaphore class.
If reentrancy is not in the design, but NotAllowed leads to exceptions due to ExecutionContext flowing unexpectedly, this mode may be the best option.
Stack = 2
A request made by a caller that is already in the semaphore is immediately executed, and shares the same semaphore slot with its parent. This nested request must exit before its parent (Strict LIFO/stack behavior). Exiting the semaphore before a child has or after the parent has will cause an InvalidOperationException to fault the Task returned from ExecuteAsync(Func<Task>, CancellationToken).
When reentrancy is a requirement, this mode helps ensure that reentrancy only happens where code enters a semaphore, then awaits on other code that itself may enter the semaphore. When a violation occurs, this semaphore transitions into a faulted state, after which any call will throw an InvalidOperationException.