DotNext by Roman Sakno

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

 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 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) throw new ArgumentException(ExceptionMessages.UnsupportedLockAcquisition, "obj"); return obj.GetUserData().GetOrSet(ReaderWriterLock, () => new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion)); } 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); } } }