DotNext by .NET Foundation and Contributors

<PackageReference Include="DotNext" Version="5.0.3" />

 LockAcquisition

public static class LockAcquisition
Provides a set of methods to acquire different types of lock.
using System; using System.Runtime.CompilerServices; using System.Threading; namespace DotNext.Threading { [NullableContext(1)] [Nullable(0)] public static class LockAcquisition { private sealed class ReaderWriterLockSlimWithRecursion : ReaderWriterLockSlim { public ReaderWriterLockSlimWithRecursion() : base(LockRecursionPolicy.SupportsRecursion) { } } private static readonly UserDataSlot<ReaderWriterLockSlim> ReaderWriterLock = new UserDataSlot<ReaderWriterLockSlim>(); [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ReaderWriterLockSlim GetReaderWriterLock<T>(this T obj) where T : class { ArgumentNullException.ThrowIfNull((object)obj, "obj"); ReaderWriterLockSlim readerWriterLockSlim = obj as ReaderWriterLockSlim; if (readerWriterLockSlim != null) return readerWriterLockSlim; bool flag = GC.GetGeneration(obj) == 2147483647; if (!flag) { bool flag2 = (obj is SemaphoreSlim || obj is WaitHandle || obj is ReaderWriterLock) ? true : false; flag = flag2; } if (flag) throw new InvalidOperationException(ExceptionMessages.UnsupportedLockAcquisition); return obj.GetUserData().GetOrSet<ReaderWriterLockSlim, ReaderWriterLockSlimWithRecursion>(ReaderWriterLock); } public static Lock.Holder AcquireReadLock<T>(this T obj) where T : class { return Lock.ReadLock(obj.GetReaderWriterLock(), false).Acquire(); } public static Lock.Holder AcquireReadLock<T>(this T obj, TimeSpan timeout) where T : class { return Lock.ReadLock(obj.GetReaderWriterLock(), false).Acquire(timeout); } public static Lock.Holder AcquireWriteLock<T>(this T obj) where T : class { return Lock.WriteLock(obj.GetReaderWriterLock()).Acquire(); } public static Lock.Holder AcquireWriteLock<T>(this T obj, TimeSpan timeout) where T : class { return Lock.WriteLock(obj.GetReaderWriterLock()).Acquire(timeout); } public static Lock.Holder AcquireUpgradeableReadLock<T>(this T obj) where T : class { return Lock.ReadLock(obj.GetReaderWriterLock(), true).Acquire(); } public static Lock.Holder AcquireUpgradeableReadLock<T>(this T obj, TimeSpan timeout) where T : class { return Lock.ReadLock(obj.GetReaderWriterLock(), true).Acquire(timeout); } } }