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);
}
}
}