ReaderWriterLockSlim Wrapper See: MonitorActionFuncWrapper.cs
using System; using System.Threading; public class ReaderWriterLockSlimActionFuncWrapper : ConcurrencyCheck, IDisposable { private bool _deadLock; private bool _disposed; private ReaderWriterLockSlim _rwl; public ReaderWriterLockSlimActionFuncWrapper(LockRecursionPolicy recursionPolicy = LockRecursionPolicy.NoRecursion) { _rwl = new ReaderWriterLockSlim(recursionPolicy); GC.SuppressFinalize(this); } public void Dispose() { Dispose(true); } public void Read(Action action) { if (action == null) throw new Exception("Action argument cannot be null"); if (CheckState()) try { _rwl.EnterReadLock(); action(); } finally { _rwl.ExitReadLock(); } else action(); } public TResult Read<TResult>(Func<TResult> func) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterReadLock(); return func(); } finally { _rwl.ExitReadLock(); } return func(); } public (TResult1, TResult2) Read<TResult1, TResult2>(Func<(TResult1, TResult2)> func) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterReadLock(); return func(); } finally { _rwl.ExitReadLock(); } return func(); } public (TResult1, TResult2) Read<TArg, TResult1, TResult2>(Func<TArg, (TResult1, TResult2)> func, TArg arg) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterReadLock(); return func(arg); } finally { _rwl.ExitReadLock(); } return func(arg); } public TResult Read<TArg, TResult>(Func<TArg, TResult> func, TArg arg) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterReadLock(); return func(arg); } finally { _rwl.ExitReadLock(); } return func(arg); } public void Read<TArg>(Action<TArg> action, TArg arg) { if (action == null) throw new Exception("Action argument cannot be null"); if (CheckState()) try { _rwl.EnterReadLock(); action(arg); } finally { _rwl.ExitReadLock(); } else action(arg); } public void Write(Action action) { if (action == null) throw new Exception("Action argument cannot be null"); if (CheckState()) try { _rwl.EnterWriteLock(); action(); } finally { _rwl.ExitWriteLock(); } else action(); } public TResult Write<TResult>(Func<TResult> func) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterWriteLock(); return func(); } finally { _rwl.ExitWriteLock(); } return func(); } public (TResult1, TResult2) Write<TResult1, TResult2>(Func<(TResult1, TResult2)> func) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterWriteLock(); return func(); } finally { _rwl.ExitWriteLock(); } return func(); } public (TResult1, TResult2) Write<TArg, TResult1, TResult2>(Func<TArg, (TResult1, TResult2)> func, TArg arg) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterWriteLock(); return func(arg); } finally { _rwl.ExitWriteLock(); } return func(arg); } public TResult Write<TArg, TResult>(Func<TArg, TResult> func, TArg arg) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterWriteLock(); return func(arg); } finally { _rwl.ExitWriteLock(); } return func(arg); } public void Write<TArg>(Action<TArg> action, TArg arg) { if (action == null) throw new Exception("Action argument cannot be null"); if (CheckState()) try { _rwl.EnterWriteLock(); action(arg); } finally { _rwl.ExitWriteLock(); } else action(arg); } public void ReadUpdate(Action action) { if (action == null) throw new Exception("Action argument cannot be null"); if (CheckState()) try { _rwl.EnterUpgradeableReadLock(); try { _rwl.EnterWriteLock(); action(); } finally { _rwl.ExitWriteLock(); } } finally { _rwl.ExitUpgradeableReadLock(); } else action(); } public TResult ReadUpdate<TResult>(Func<TResult> func) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterUpgradeableReadLock(); try { _rwl.EnterWriteLock(); return func(); } finally { _rwl.ExitWriteLock(); } } finally { _rwl.ExitUpgradeableReadLock(); } return func(); } public (TResult1, TResult2) ReadUpdate<TResult1, TResult2>(Func<(TResult1, TResult2)> func) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterUpgradeableReadLock(); try { _rwl.EnterWriteLock(); return func(); } finally { _rwl.ExitWriteLock(); } } finally { _rwl.ExitUpgradeableReadLock(); } return func(); } public (TResult1, TResult2) ReadUpdate<TArg, TResult1, TResult2>(Func<TArg, (TResult1, TResult2)> func, TArg arg) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterUpgradeableReadLock(); try { _rwl.EnterWriteLock(); return func(arg); } finally { _rwl.ExitWriteLock(); } } finally { _rwl.ExitUpgradeableReadLock(); } return func(arg); } public TResult ReadUpdate<TArg, TResult>(Func<TArg, TResult> func, TArg arg) { if (func == null) throw new Exception("Func argument cannot be null"); if (CheckState()) try { _rwl.EnterUpgradeableReadLock(); try { _rwl.EnterWriteLock(); return func(arg); } finally { _rwl.ExitWriteLock(); } } finally { _rwl.ExitUpgradeableReadLock(); } return func(arg); } public void ReadUpdate<TArg>(Action<TArg> action, TArg arg) { if (action == null) throw new Exception("Action argument cannot be null"); if (CheckState()) try { _rwl.EnterUpgradeableReadLock(); try { _rwl.EnterWriteLock(); action(arg); } finally { _rwl.ExitWriteLock(); } } finally { _rwl.ExitUpgradeableReadLock(); } else action(arg); } ~ReaderWriterLockSlimActionFuncWrapper() { if (_rwl != null) _rwl.Dispose(); } protected virtual void Dispose(bool disposing) { if (_disposed) throw new Exception("Already Disposed"); try { _rwl.Dispose(); _disposed = true; _rwl = null; } catch (SynchronizationLockException) when (disposing) { _deadLock = true; } finally { if (!_disposed && disposing) GC.ReRegisterForFinalize(this); } } }