Last active
December 20, 2015 09:29
-
-
Save felipegtx/6107975 to your computer and use it in GitHub Desktop.
Lock manager for C# (wrapping a RWLSlim implementation)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Given any object instance | |
var list = new List<int>(); | |
/// We create the simple locker instance | |
var locker = new SimpleLocker(); | |
Parallel.For(0, 10000, i=> | |
{ | |
/// Safelly modify it | |
locker.WriteVoid(() => list.Add(i)); | |
/// Safelly ready it | |
Console.WriteLine(locker.Read(() => list.Count)); | |
/// Optionally we can do it as follows | |
Console.WriteLine( | |
locker.UpgradeableRead(()=>{ | |
locker.WriteVoid(()=> list.Add(i)); | |
return locker.Count; | |
}) | |
); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading; | |
namespace Threading | |
{ | |
public sealed class SimpleLocker | |
{ | |
private ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(); | |
private int _lockTimeout = 1000; | |
public SimpleLocker(int lockTimeout = 1000) | |
{ | |
_lockTimeout = lockTimeout; | |
} | |
public ReturnType Read<ReturnType>(Func<ReturnType> what) | |
{ | |
if (!_locker.TryEnterReadLock(_lockTimeout)) { throw new TimeoutException(); } | |
try | |
{ | |
var result = what(); | |
_locker.ExitReadLock(); | |
return result; | |
} | |
catch | |
{ | |
if (_locker.IsReadLockHeld) | |
{ | |
_locker.ExitReadLock(); | |
} | |
throw; | |
} | |
} | |
public ReturnType UpgradeableRead<ReturnType>(Func<ReturnType> what) | |
{ | |
if (!_locker.TryEnterUpgradeableReadLock(_lockTimeout)) { throw new TimeoutException(); } | |
try | |
{ | |
var result = what(); | |
_locker.ExitUpgradeableReadLock(); | |
return result; | |
} | |
catch | |
{ | |
if (_locker.IsUpgradeableReadLockHeld) | |
{ | |
_locker.ExitUpgradeableReadLock(); | |
} | |
throw; | |
} | |
} | |
public ReturnType Write<ReturnType>(Func<ReturnType> what) | |
{ | |
if (!_locker.TryEnterWriteLock(_lockTimeout)) { throw new TimeoutException(); } | |
try | |
{ | |
var result = what(); | |
_locker.ExitWriteLock(); | |
return result; | |
} | |
catch | |
{ | |
if (_locker.IsWriteLockHeld) | |
{ | |
_locker.ExitWriteLock(); | |
} | |
throw; | |
} | |
} | |
public void ReadVoid(Action what) | |
{ | |
if (!_locker.TryEnterReadLock(_lockTimeout)) { throw new TimeoutException(); } | |
try | |
{ | |
what(); | |
_locker.ExitReadLock(); | |
} | |
catch | |
{ | |
if (_locker.IsReadLockHeld) | |
{ | |
_locker.ExitReadLock(); | |
} | |
throw; | |
} | |
} | |
public void UpgradeableReadVoid(Action what) | |
{ | |
if (!_locker.TryEnterUpgradeableReadLock(_lockTimeout)) { throw new TimeoutException(); } | |
try | |
{ | |
what(); | |
_locker.ExitUpgradeableReadLock(); | |
} | |
catch | |
{ | |
if (_locker.IsUpgradeableReadLockHeld) | |
{ | |
_locker.ExitUpgradeableReadLock(); | |
} | |
throw; | |
} | |
} | |
public void WriteVoid(Action what) | |
{ | |
if (!_locker.TryEnterWriteLock(_lockTimeout)) { throw new TimeoutException(); } | |
try | |
{ | |
what(); | |
_locker.ExitWriteLock(); | |
} | |
catch | |
{ | |
if (_locker.IsWriteLockHeld) | |
{ | |
_locker.ExitWriteLock(); | |
} | |
throw; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment