A Read-Writer Locker designed in such a way that hard locks cannot happen, upgrading from read locks to write locks are intuitive, and highly nested locking is allowed.
Forked from jpmikkers' ReaderWriterLockAlt located at http://readerwriterlockalt.codeplex.com/
. As such, this also supports .NET 2.0+. If you would like to learn how to design your own, or you would like to help with this project, please start there.
Useful wherever multi-threaded programming is being used on a shared resource. This could be inside background workers, custom threads, threads from the thread pool class, Asynchronous Programming (such as Nito.Async), or PFX (Parallel class, PLINQ, and Parallel Tasks).
Note: If you would like regular locking (i.e. SyncLocks/locks) that cannot be hard locked, simply use GetSyncLock() or GetLock() according to your programming language/preference.
- No hard locks when dealing with complex locking.
- No manual upgrade locks. Upgrading locks is as simple as nesting a write lock inside a read lock.
- Ability to guarantee a responsive UI when hard locking would otherwise occur. Just set ReadWriteLocker.UseThisThreadAsPriorityThread = true in the main program where the UI thread is running.
- Compatibility with ReaderWriterLock and ReaderWriterLockSlim through wrapper classes. This allows migration of existing code to work with this new locker, needing only a minimal amount of code changes.
- The ability to determine where hard locks would occur. Then once it is guaranteed to never happen, you can remove the overhead associated with hard lock prevention by changing a parameter in the constructor.
- Aborting a thread or forgetting to dispose the locker in the middle of thread locking shouldn't cause stability issues. It is still recommended to dispose the locker in both cases. (not finished yet)
- Collections included which utilizes this thread locker to transparently make itself thread safe. It also allows collections to know when they are being iterated over, and when iteration completes--useful in caching modifications, then applying them when iteration finishes. (not completed)
- Portability. The ideas behind this locking mechanism can be applied to many different languages and platforms.
This project uses a new Tri-License Choice MIT/L-GPL/MS-PL. As such, you have a choice of choosing MIT, L-GPL v2 or v3, or MS-PL. Or you can choose to use the tri-license and let others have their choice. While using this tri-license, MIT will be used in regards to the code, and L-GPL v2 for patents (so algorithms remain open source). Only when MS-PL is chosen, does it apply (dropping MIT and L-GPL).
The typical lock(A) locking on lock(B), and lock(B) locking on lock(A). I detect when it happens, and let one thread "run its course" to solve this issue.
ReadWriteLocker Lock = New ReadWriteLocker(True);
using (IDisposable ReadLock = Lock.GetReadLock())
// Perform any reading you might need, like iterating through a List.
using (IDisposable WriteLock = Lock.GetWriteLock())
// Perform any writing you may need, like adding items to a List.
} // End using
} // End using
Dim Lock As ReadWriteLocker(True)
Using ReadLock As IDisposable = Lock.GetReadLock()
' Perform any reading you might need, like iterating through a List.
Using WriteLock As IDisposable = Lock.GetWriteLock()
' Perform any writing you may need, like adding items to that List.