Named Async Locks
As application complexity grows, you will eventually need a scalable way to serialize queries and updates to resources.
For Example
You might have a document platform, that provides collaborative editing.
In which case, there may be multiple clients submitting changes, simultaneously.
And, these changes all have to be incorporated as a serialized list of individual changes to a document.
Since multiple such documents may be in-flux, the easiest way to serialize changes to each is with asynchronous semaphore.
Below is how to manage changes to these documents, using a process-wide set of named, asynchronous locks.
Implementation
For our document editing use case, above, we will use this library: https://github.com/LeeWhite187/AsyncKeyedLock
NOTE: The above repo is actually a fork of the original, here: https://github.com/MarkCiliaVincenti/AsyncKeyedLock
Install AsyncKeyedLock from Nuget.
It's currently published as .NET Standard 2.0, so it's quite compatible across .NET versions.
Best way to use this library is to register it with DI, on startup, with this:
// Setup the global session update serializer, here...
{
// We want the session serializer to allow one and only one thread/task to update
// a particular document (or other top-level entity) at a time...
services.AddSingleton(sp =>
{
// Create an instance that allows only one thread/task in at a time...
var asyncKeyedLocker1 = new AsyncKeyedLocker<string>(new AsyncKeyedLockOptions(maxCount: 1));
// Return it as the singleton...
return asyncKeyedLocker1;
});
}