From 89891f0d3384f83219ade3557bc1c81c89458f28 Mon Sep 17 00:00:00 2001 From: Mark Cilia Vincenti Date: Mon, 10 Apr 2023 09:21:40 +0200 Subject: [PATCH] Implemented IDisposable. --- AsyncKeyedLock/AsyncKeyedLock.csproj | 8 ++++---- AsyncKeyedLock/AsyncKeyedLockDictionary.cs | 23 +++++++++++++++++++++- AsyncKeyedLock/AsyncKeyedLockPool.cs | 7 ++++++- AsyncKeyedLock/AsyncKeyedLocker.cs | 10 +++++++++- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/AsyncKeyedLock/AsyncKeyedLock.csproj b/AsyncKeyedLock/AsyncKeyedLock.csproj index 10b6e9e..a781f2a 100644 --- a/AsyncKeyedLock/AsyncKeyedLock.csproj +++ b/AsyncKeyedLock/AsyncKeyedLock.csproj @@ -8,16 +8,16 @@ https://github.com/MarkCiliaVincenti/AsyncKeyedLock MIT MIT - 6.2.0 + 6.2.1 logo.png - Created an alternate method for locking using striped locks. For a list of pros and cons of both techniques, please visit the wiki at https://github.com/MarkCiliaVincenti/AsyncKeyedLock/wiki + Implemented IDisposable. An asynchronous .NET Standard 2.0 library that allows you to lock based on a key (keyed semaphores), limiting concurrent threads sharing the same key to a specified number, with optional pooling for reducing memory allocations. © 2023 Mark Cilia Vincenti async,lock,key,keyed,semaphore,striped,dictionary,concurrentdictionary,pooling,duplicate,synchronization git false - 6.2.0.0 - 6.2.0.0 + 6.2.1.0 + 6.2.1.0 README.md true true diff --git a/AsyncKeyedLock/AsyncKeyedLockDictionary.cs b/AsyncKeyedLock/AsyncKeyedLockDictionary.cs index fed63f7..e7d3a07 100644 --- a/AsyncKeyedLock/AsyncKeyedLockDictionary.cs +++ b/AsyncKeyedLock/AsyncKeyedLockDictionary.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -6,7 +7,7 @@ namespace AsyncKeyedLock { - internal sealed class AsyncKeyedLockDictionary : ConcurrentDictionary> + internal sealed class AsyncKeyedLockDictionary : ConcurrentDictionary>, IDisposable { public int MaxCount { get; private set; } = 1; private readonly AsyncKeyedLockPool _pool; @@ -172,5 +173,25 @@ public void ReleaseWithoutSemaphoreRelease(AsyncKeyedLockReleaser releaser --releaser.ReferenceCount; Monitor.Exit(releaser); } + + public void Dispose() + { + foreach (var semaphore in Values) + { + try + { + semaphore.Dispose(); + } + catch + { + // do nothing + } + } + Clear(); + if (PoolingEnabled) + { + _pool.Dispose(); + } + } } } diff --git a/AsyncKeyedLock/AsyncKeyedLockPool.cs b/AsyncKeyedLock/AsyncKeyedLockPool.cs index 6450338..6f8aa64 100644 --- a/AsyncKeyedLock/AsyncKeyedLockPool.cs +++ b/AsyncKeyedLock/AsyncKeyedLockPool.cs @@ -4,7 +4,7 @@ namespace AsyncKeyedLock { - internal sealed class AsyncKeyedLockPool + internal sealed class AsyncKeyedLockPool : IDisposable { private readonly BlockingCollection> _objects; private readonly Func> _objectGenerator; @@ -34,6 +34,11 @@ public AsyncKeyedLockPool(Func> objectGenerat } } + public void Dispose() + { + _objects.Dispose(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public AsyncKeyedLockReleaser GetObject(TKey key) { diff --git a/AsyncKeyedLock/AsyncKeyedLocker.cs b/AsyncKeyedLock/AsyncKeyedLocker.cs index 9b35626..27339b9 100644 --- a/AsyncKeyedLock/AsyncKeyedLocker.cs +++ b/AsyncKeyedLock/AsyncKeyedLocker.cs @@ -153,7 +153,7 @@ public AsyncKeyedLocker(Action options, int concurrencyLe /// /// Represents a thread-safe keyed locker that allows you to lock based on a key (keyed semaphores), only allowing a specified number of concurrent threads that share the same key. /// - public class AsyncKeyedLocker where TKey : notnull + public class AsyncKeyedLocker : IDisposable where TKey : notnull { private readonly AsyncKeyedLockDictionary _dictionary; /// @@ -1013,5 +1013,13 @@ public int GetCurrentCount(TKey key) { return MaxCount - GetRemainingCount(key); } + + /// + /// Disposes the AsyncKeyedLocker. + /// + public void Dispose() + { + _dictionary.Dispose(); + } } } \ No newline at end of file