GitHub - NGPVAN/DistributedLock: DEPRECATED A .NET library for distributed synchronization · GitHub
Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

NGPVAN/DistributedLock

 
 

Repository files navigation

DistributedLock

DistributedLock is a lightweight .NET library that makes it easy to set up and use system-wide or fully distributed locks.

DistributedLock is available for download as a NuGet package.

System-wide locks

System-wide locks are great for synchronizing between processes or .NET application domains:

var myLock = new SystemDistributedLock("SystemLock");

using (myLock.Acquire())
{
	// this block of code is protected by the lock!
}

Fully distributed locks

DistributedLock allows you to easily leverage MSFT SQLServer's application lock functionality to provide synchronization between machines in a distributed environment. To use this functionality, you'll need a SQLServer connection string:

var connectionString = ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;
var myLock = new SqlDistributedLock("SqlLock", connectionString);

using (myLock.Acquire())
{
	// this block of code is protected by the lock!
}

As of version 1.1.0, SqlDistributedLocks can now be scoped to existing DbTransaction and/or DbConnection objects as an alternative to passing a connection string directly (in which case the lock manages its own connection).

Naming locks

For all types of locks, the name of the lock defines its identity within its scope. While in general most names will work, the names are ultimately constrained by the underlying technologies used for locking. If you don't want to worry (particularly if when generating names dynamically), you can use the GetSafeLockName method each lock type to convert an arbitrary string into a consistent valid lock name:

string baseName = // arbitrary logic
var lockName = SqlDistributedLock.GetSafeLockName(baseName);
var myLock = new SqlDistributedLock(lockName);

Other features

TryLock

All locks support a "try" mechanism so that you can attempt to claim the lock without committing to it:

using (var handle = myLock.TryAcquire())
{
	if (handle != null)
	{
		// I have the lock!
	}
	else
	{
		// someone else has it!
	}
}

Async

All locks support async acquisition so that you don't need to consume threads waiting for locks to become available:

using (await myLock.AcquireAsync())
{
	// this block of code is protected by the lock!
	
	// locks can be used to protect async code
	await webClient.DownloadStringAsync(...);
}

Note that because of this locks do not have thread affinity unlike the Monitor and Mutex .NET synchronization classes and are not re-entrant.

Timeouts

All lock methods support specifying timeouts after which point TryAcquire calls will return null and Acquire calls will throw a TimeoutException:

// wait up to 5 seconds to acquire the lock
using (var handle = myLock.TryAcquire(TimeSpan.FromSeconds(5)))
{
	if (handle != null)
	{
		// I have the lock!
	}
	else
	{
		// timed out waiting for someone else to give it up
	}
}

Cancellation

All lock methods support passing a CancellationToken which, if triggered, will break out of the wait:

// acquire the lock, unless someone cancels us
CancellationToken token = ...
using (myLock.Acquire(cancellationToken: token))
{
	// this block of code is protected by the lock!
}

Release notes

  • 1.1.0 Added support for SQL distributed locks scoped to existing connections/transactions
  • 1.0.1 Minor fix when using infinite timeouts
  • 1.0.0 Initial release

About

DEPRECATED A .NET library for distributed synchronization

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors

Languages

  • C# 100.0%