DotNext by Roman Sakno

<PackageReference Include="DotNext" Version="0.3.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(); private static readonly Func<ReaderWriterLockSlim> ReaderWriterLockFactory = () => new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); private static Lock Acquire<T>(T obj, Converter<T, Lock> locker) where T : class { Lock result = locker(obj); result.Acquire(); return result; } private static Lock Acquire<T>(T obj, Converter<T, Lock> locker, TimeSpan timeout) where T : class { Lock result = locker(obj); if (!result.TryAcquire(timeout)) throw new TimeoutException(); return result; } public static Lock Lock<T>(this T obj) where T : class { return Acquire(obj, DotNext.Threading.Lock.Monitor); } public static Lock Lock<T>(this T obj, TimeSpan timeout) where T : class { return Acquire(obj, DotNext.Threading.Lock.Monitor, timeout); } public static Lock Lock(this SemaphoreSlim semaphore) { return Acquire(semaphore, DotNext.Threading.Lock.Semaphore); } public static Lock Lock(this SemaphoreSlim semaphore, TimeSpan timeout) { return Acquire(semaphore, DotNext.Threading.Lock.Semaphore, timeout); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ReaderWriterLockSlim GetReaderWriterLock<T>(this T obj) where T : class { return obj.GetUserData().GetOrSet(ReaderWriterLock, ReaderWriterLockFactory); } public static Lock ReadLock<T>(this T obj) where T : class { return obj.GetReaderWriterLock().ReadLock(); } public static Lock ReadLock<T>(this T obj, TimeSpan timeout) where T : class { return obj.GetReaderWriterLock().ReadLock(timeout); } public static Lock ReadLock(this ReaderWriterLockSlim rwLock) { return Acquire(rwLock, DotNext.Threading.Lock.ReadLock); } public static Lock ReadLock(this ReaderWriterLockSlim rwLock, TimeSpan timeout) { return Acquire(rwLock, DotNext.Threading.Lock.ReadLock, timeout); } public static Lock WriteLock<T>(this T obj) where T : class { return obj.GetReaderWriterLock().WriteLock(); } public static Lock WriteLock<T>(this T obj, TimeSpan timeout) where T : class { return obj.GetReaderWriterLock().WriteLock(timeout); } public static Lock WriteLock(this ReaderWriterLockSlim rwLock) { return Acquire(rwLock, DotNext.Threading.Lock.WriteLock); } public static Lock WriteLock(this ReaderWriterLockSlim rwLock, TimeSpan timeout) { return Acquire(rwLock, DotNext.Threading.Lock.WriteLock, timeout); } public static Lock UpgradableReadLock<T>(this T obj) where T : class { return obj.GetReaderWriterLock().UpgradableReadLock(); } public static Lock UpgradableReadLock<T>(this T obj, TimeSpan timeout) where T : class { return obj.GetReaderWriterLock().UpgradableReadLock(timeout); } public static Lock UpgradableReadLock(this ReaderWriterLockSlim rwLock) { return Acquire(rwLock, DotNext.Threading.Lock.UpgradableReadLock); } public static Lock UpgradableReadLock(this ReaderWriterLockSlim rwLock, TimeSpan timeout) { return Acquire(rwLock, DotNext.Threading.Lock.UpgradableReadLock, timeout); } } }