![]() |
VOOZH | about |
dotnet add package AsyncReaderWriterLockSlim --version 1.0.0
NuGet\Install-Package AsyncReaderWriterLockSlim -Version 1.0.0
<PackageReference Include="AsyncReaderWriterLockSlim" Version="1.0.0" />
<PackageVersion Include="AsyncReaderWriterLockSlim" Version="1.0.0" />Directory.Packages.props
<PackageReference Include="AsyncReaderWriterLockSlim" />Project file
paket add AsyncReaderWriterLockSlim --version 1.0.0
#r "nuget: AsyncReaderWriterLockSlim, 1.0.0"
#:package AsyncReaderWriterLockSlim@1.0.0
#addin nuget:?package=AsyncReaderWriterLockSlim&version=1.0.0Install as a Cake Addin
#tool nuget:?package=AsyncReaderWriterLockSlim&version=1.0.0Install as a Cake Tool
This is an alternative to .NET's
ReaderWriterLockSlim
with a similar functionality, but can be used in async methods. Due to its async-readiness, it
does not support recursive locks (see section Differences).
Another alternative: https://dotnet.github.io/dotNext/api/DotNext.Threading.AsyncReaderWriterLock.html from https://github.com/dotnet/dotNext
The lock can have different modes:
When a task or thread ("execution flow") tries to enter a write mode lock while at least one read mode lock is active, it is blocked until the last read mode lock is released.
When a task or thread tries to enter a read mode lock while a write mode lock is active, it is blocked until the write mode lock is released.
If, while other read mode locks are active and the current task or thread waits to enter the write mode lock, another task or thread tries to enter a read mode lock, it is blocked until the current task or thread released the write mode lock (or canceled the wait operation), which means writers are favored in this case.
Also, when a write mode lock is released while there are one or more execution flows trying to enter a write mode lock and also one or more execution flows trying to enter a read mode lock, writers are favored.
The lock provides synchronous Enter...() methods for the different lock modes that block
until the lock has been acquired, and asynchronous Enter...Async() methods that
"block asynchronously" by returning a
Task that
will complete once the lock has been acquired.
For each Enter...() and Enter...Async() method there is also a TryEnter...() and
TryEnter...Async() method that allow you to specify an integer time-out, and return a Boolean
that indicates if the lock could be acquired within that time-out.
You must make sure to call the corresponding Exit...() method to release the lock once you
don't need it anymore.
Additionally, the AsyncReaderWriterLockSlimExtension class contains extension methods
that return an IDisposable so that the lock can be used with a using block.
When using the AsyncReaderWriterLockSlim for write mode locks only, performance is
significantly slower than simply using a
SemaphoreSlim
due to the additional overhead. Therefore, use the AsyncReaderWriterLockSlim only
when there are far more readers than writers.
This implementation has the following differences to .NET's
ReaderWriterLockSlim:
await
operator between entering and releasing the lock.EnterReadLock, it has asynchronous methods
like EnterReadLockAsync which can be called in async methods, so that the current thread
is not blocked while waiting for the lock.CancellationToken
when entering a lock to cancel the wait operation.This implementation has the following differences to Nito.AsyncEx'
AsyncReaderWriterLock:
IDisposable, it has Enter...() and Exit...() methods
similar to .NET's ReaderWriterLockSlim. However, the class AsyncReaderWriterLockSlimExtension
provides extension methods that return an IDisposable.CancellationToken that allows you to cancel the wait operation,
you can supply an integer time-out to the TryEnter...() methods.Enter...() methods with an already canceled
CancellationToken,
the method does not try to acquire the lock, but instead throws a OperationCanceledException,
which matches the behavior of SemaphoreSlim. <br>
To try to acquire the lock without blocking, you can call one of the Try... methods without
specifying a timeout (or specify a timeout of 0).DowngradeWriteLockToReadLock().SemaphoreSlim),
which means there is no guarantee in which order threads will acquire the lock (e.g. if
multiple threads want to get a write lock at the same time using synchronous methods).<br>
Fairness can actually lead to problems like lock convoys, and shouldn't be needed in most cases.Note: The supported maximum number of concurrent locks in read mode is limited to int.MaxValue (2147483647).
The lock internally uses
SemaphoreSlim
to implement wait functionality.
| Method | Description |
|---|---|
Dispose () |
Releases all resources used by the AsyncReaderWriterLockSlim. |
EnterReadLock (CancellationToken) |
Enters the lock in read mode. |
EnterReadLockAsync (CancellationToken) |
Asynchronously enters the lock in read mode. |
TryEnterReadLock (Int32, CancellationToken) |
Tries to enter the lock in read mode, with an optional integer time-out. |
TryEnterReadLockAsync (Int32, CancellationToken) |
Tries to asynchronously enter the lock in read mode, with an optional integer time-out. |
EnterWriteLock (CancellationToken) |
Enters the lock in write mode. |
EnterWriteLockAsync (CancellationToken) |
Asynchronously enters the lock in write mode. |
TryEnterWriteLock (Int32, CancellationToken) |
Tries to enter the lock in write mode, with an optional integer time-out. |
TryEnterWriteLockAsync (Int32, CancellationToken) |
Tries to asynchronously enter the lock in write mode, with an optional integer time-out. |
DowngradeWriteLockToReadLock () |
Downgrades the lock from write mode to read mode. |
ExitReadLock () |
Exits read mode. |
ExitWriteLock () |
Exits write mode. |
Enter the lock in read mode within an async method:
private async Task TestReadModeAsync(AsyncReaderWriterLockSlim asyncLock)
{
// Asynchronously enter the lock in read mode. The task completes after the lock
// has been acquired.
await asyncLock.EnterReadLockAsync();
try
{
// Use Task.Delay to simulate asynchronous work, which means a different thread
// might continue execution after this point.
await Task.Delay(200);
}
finally
{
asyncLock.ExitReadLock();
}
}
Enter the lock in read mode within an async method within an using block:
private async Task TestReadModeAsync(AsyncReaderWriterLockSlim asyncLock)
{
// Asynchronously enter the lock in read mode. The task completes after the lock
// has been acquired.
// As the Get...() methods return a IDisposeable, you can use the lock within an
// "using" block.
using (var myLock = await asyncLock.GetReadLockAsync())
{
// Use Task.Delay to simulate asynchronous work, which means a different thread
// might continue execution after this point.
await Task.Delay(200);
}
}
Enter the lock in write mode in a synchronous method, using a timeout:
private void TestWriteMode(AsyncReaderWriterLockSlim asyncLock)
{
// Try to enter the lock within 2 seconds.
if (asyncLock.TryEnterWriteLock(2000))
{
try
{
// Simulate some work...
Thread.Sleep(200);
}
finally
{
asyncLock.ExitWriteLock();
}
}
else
{
// We could not enter the lock within the timeout...
}
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on AsyncReaderWriterLockSlim:
| Package | Downloads |
|---|---|
|
WiYun.Core
Wima Platform for building a business application. |
|
|
GoreRemoting
Grpc Remoting library for migration from .NET Remoting |
|
|
GoreRemoting.Serialization.BinaryFormatter
Grpc Remoting library for migration from .NET Remoting |
|
|
GoreRemoting.Serialization.Json
Grpc Remoting library for migration from .NET Remoting |
|
|
GoreRemoting.Serialization.MemoryPack
Grpc Remoting library for migration from .NET Remoting |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 193,066 | 4/4/2024 |