KeyedLock<TKey> Class
Provides a synchronous lock mechanism that locks based on a key, allowing concurrent operations on different keys.
public sealed class KeyedLock<TKey> where TKey : notnullType parameters
TKey- The type of the key.
Remarks
The lock is thread-affine: it is built on Lock, which requires the lease to be released on the thread that acquired it. The critical section must therefore stay on one thread and must not await. Use KeyedAsyncLock<TKey> for asynchronous code.
Example
var keyedLock = new KeyedLock<string>(StringComparer.Ordinal);
var updateCounts = new ConcurrentDictionary<string, int>(StringComparer.Ordinal);
void ProcessUser(string userId)
{
using (keyedLock.Lock(userId))
{
// Only one operation per userId at a time
// Multiple different userIds can be processed concurrently
var count = updateCounts.GetValueOrDefault(userId);
updateCounts[userId] = count + 1;
}
}
Parallel.Invoke(() => ProcessUser("alice"), () => ProcessUser("alice"), () => ProcessUser("bob"));
Assert.Equal(2, updateCounts["alice"]);
Assert.Equal(1, updateCounts["bob"]);Constructors
| Name | Description |
|---|---|
| KeyedLock() | Initializes a new instance of the KeyedLock<TKey> class. |
| KeyedLock(IEqualityComparer<TKey>?) | Initializes a new instance of the KeyedLock<TKey> class with the specified equality comparer. |
KeyedLock overloads
KeyedLock()
KeyedLock.csInitializes a new instance of the KeyedLock<TKey> class.
public KeyedLock()KeyedLock(IEqualityComparer<TKey>?)
KeyedLock.csInitializes a new instance of the KeyedLock<TKey> class with the specified equality comparer.
public KeyedLock(IEqualityComparer<TKey>? comparer)Parameters
comparerIEqualityComparer<TKey>?- The equality comparer to use when comparing keys.
Methods
| Name | Description |
|---|---|
| Lock(TKey) | Acquires the lock for the specified key. |
Lock(TKey)
KeyedLock.csAcquires the lock for the specified key.
public IDisposable Lock(TKey key)Parameters
keyTKey- The key to lock on.
Returns
IDisposable A disposable object. Disposing the object releases the lock.
Remarks
The returned object must be disposed on the thread that called this method. Disposing it on another thread throws SynchronizationLockException and leaves the underlying lock held; the object is not consumed by such a failed disposal, so the owning thread can still dispose it to release the lock.