using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; public class KeyedSemaphore { private readonly ConcurrentDictionary<string, Lazy<SemaphoreSlim>> _semaphores = new ConcurrentDictionary<string, Lazy<SemaphoreSlim>>(); public async Task<IDisposable> LockAsync(string key) { var semaphore = _semaphores.GetOrAdd(key, k => new Lazy<SemaphoreSlim>(() => new SemaphoreSlim(1, 1))).Value; await semaphore.WaitAsync(); return new Releaser(this, key); } private void Release(string key) { if (_semaphores.TryGetValue(key, out var lazySemaphore)) { var semaphore = lazySemaphore.Value; semaphore.Release(); // Opruimen als er geen wachtende taken meer zijn if (semaphore.CurrentCount == 1) { _semaphores.TryRemove(key, out _); } } } private class Releaser : IDisposable { private readonly KeyedSemaphore _keyedSemaphore; private readonly string _key; public Releaser(KeyedSemaphore keyedSemaphore, string key) { _keyedSemaphore = keyedSemaphore; _key = key; } public void Dispose() { _keyedSemaphore.Release(_key); } } }
Or use a library like: https://github.com/amoerie/keyed-semaphores
938700cookie-checkC# KeyedSemaphore