DotNext by Roman Sakno

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

 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 { public static class LockAcquisition { private sealed class ReaderWriterLockSlimWithRecursion : ReaderWriterLockSlim { public ReaderWriterLockSlimWithRecursion() : base(LockRecursionPolicy.SupportsRecursion) { } } private static readonly UserDataSlot<ReaderWriterLockSlim> ReaderWriterLock = UserDataSlot<ReaderWriterLockSlim>.Allocate(); [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ReaderWriterLockSlim GetReaderWriterLock<T>(this T obj) where T : class { if (obj == null) throw new ArgumentNullException("obj"); ReaderWriterLockSlim readerWriterLockSlim = obj as ReaderWriterLockSlim; if (readerWriterLockSlim != null) return readerWriterLockSlim; if (!(obj is SemaphoreSlim) && !(obj is WaitHandle) && !(obj is ReaderWriterLock)) { string text = obj as string; if (text == null || string.IsInterned(text) == null) return obj.GetUserData().GetOrSet<ReaderWriterLockSlim, ReaderWriterLockSlimWithRecursion>(ReaderWriterLock); } throw new InvalidOperationException(ExceptionMessages.UnsupportedLockAcquisition); } 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); } } }