diff --git a/.gitignore b/.gitignore
index d4b26077..7e8d6cb6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,3 +53,5 @@ StyleCop.Cache
packages/
credentials/
+
+publish/
\ No newline at end of file
diff --git a/DistributedLock.Core/DistributedLock.Core.csproj b/DistributedLock.Core/DistributedLock.Core.csproj
index 2bb6ba2d..4779cea0 100644
--- a/DistributedLock.Core/DistributedLock.Core.csproj
+++ b/DistributedLock.Core/DistributedLock.Core.csproj
@@ -52,8 +52,8 @@
-
+
-
+
\ No newline at end of file
diff --git a/DistributedLockCodeGen/ApiDocGenerator.cs b/DistributedLockCodeGen/ApiDocGenerator.cs
new file mode 100644
index 00000000..10419fc5
--- /dev/null
+++ b/DistributedLockCodeGen/ApiDocGenerator.cs
@@ -0,0 +1,108 @@
+using Medallion.Shell;
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+namespace DistributedLockCodeGen
+{
+ internal class ApiDocGenerator
+ {
+ private const string DotNetPath = @"C:\Program Files\dotnet\dotnet.exe";
+ private const string DocsFramework = "netstandard2.1";
+ private const string DocsFolder = "docs";
+ private const string ApiFolder = "api";
+
+ private static readonly Shell Shell = new(
+ options => options.ThrowOnError()
+ .Command(c => c.RedirectStandardErrorTo(Console.Error).RedirectTo(Console.Out))
+ );
+
+
+#if RELEASE
+ [Test]
+#endif
+ public async Task GenerateApiDocs()
+ {
+ var result = await Shell.Run(DotNetPath, new[] { "tool", "install", "DefaultDocumentation.Console", "-g" }, options: o => o.ThrowOnError(false)).Task;
+ Assert.That(result.ExitCode, Is.EqualTo(0).Or.EqualTo(1)); // 1 == already installed
+
+ var tempDirectory = Path.Combine(Path.GetTempPath(), $"DistributedLockApiDocGen_{DateTime.UtcNow.Ticks}");
+ try
+ {
+ Directory.CreateDirectory(tempDirectory);
+ await GenerateApiDocsAsync(tempDirectory);
+ }
+ finally
+ {
+ DeleteDirectoryIfExists(tempDirectory);
+ }
+ }
+
+ private static async Task GenerateApiDocsAsync(string tempDirectory)
+ {
+ var publishDirectory = Path.Combine(CodeGenHelpers.SolutionDirectory, DocsFolder, ApiFolder);
+ DeleteDirectoryIfExists(publishDirectory);
+
+ var linksPath = Path.Combine(tempDirectory, "links");
+ Directory.CreateDirectory(linksPath);
+
+ var contentPath = Path.Combine(tempDirectory, "output");
+ Directory.CreateDirectory(contentPath);
+
+ var projectDirectories = Directory.GetDirectories(CodeGenHelpers.SolutionDirectory, "DistributedLock.*")
+ .Where(d => !d.EndsWith(".Tests", StringComparison.OrdinalIgnoreCase) && !d.EndsWith("DistributedLock", StringComparison.OrdinalIgnoreCase));
+
+ for (var i = 0; i < 2; ++i)
+ {
+ foreach (var projectDirectory in projectDirectories)
+ {
+ await GenerateApiDocsAsync(projectDirectory);
+ }
+ }
+
+ Directory.Move(contentPath, publishDirectory);
+
+ async Task GenerateApiDocsAsync(string projectDirectory)
+ {
+ var projectName = Path.GetFileName(projectDirectory);
+ var binDirectory = Path.Combine(projectDirectory, "bin", "Release", DocsFramework);
+ var outputDirectoryPath = Path.Combine(contentPath, projectName);
+
+ var config = new Dictionary
+ {
+ { "AssemblyFilePath", Path.Combine(binDirectory, projectName + ".dll") },
+ { "DocumentationFilePath", Path.Combine(binDirectory, projectName + ".xml") },
+ { "ProjectDirectoryPath", projectDirectory },
+ { "OutputDirectoryPath", outputDirectoryPath },
+ { "AssemblyPageName", "README" },
+ { "GeneratedAccessModifiers", "Public,Protected,ProtectedInternal" },
+ { "GeneratedPages", "Assembly,Namespaces,Types,Members" },
+ { "LinksOutputFilePath", Path.Combine(linksPath, projectName + ".txt") },
+ { "LinksBaseUrl", $"https://github.com/madelson/DistributedLock/tree/default-documentation/{DocsFolder}/{ApiFolder}/{projectName}/" },
+ { "ExternLinksFilePaths", new string[] { Path.Combine(linksPath, "*.txt") } },
+ { "FileNameFactory", "NameAndMd5Mix" },
+ { "Markdown.IgnoreLineBreak", true },
+ };
+
+ var configFilePath = Path.Combine(tempDirectory, projectName + "_config.json");
+ File.WriteAllText(configFilePath, JsonSerializer.Serialize(config));
+
+ DeleteDirectoryIfExists(outputDirectoryPath);
+ await Shell.Run("defaultdocumentation", "-j", configFilePath).Task;
+ }
+ }
+
+ private static void DeleteDirectoryIfExists(string directory)
+ {
+ if (Directory.Exists(directory))
+ {
+ Directory.Delete(directory, recursive: true);
+ }
+ }
+ }
+}
diff --git a/DistributedLockCodeGen/DistributedLockCodeGen.csproj b/DistributedLockCodeGen/DistributedLockCodeGen.csproj
index ebf81e62..6463b066 100644
--- a/DistributedLockCodeGen/DistributedLockCodeGen.csproj
+++ b/DistributedLockCodeGen/DistributedLockCodeGen.csproj
@@ -1,7 +1,8 @@
- netcoreapp3.1
+ net6.0
+ Latest
false
enable
@@ -13,6 +14,7 @@
+
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock..ctor.5tADfQ9q5nXUDj477SWvHg.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock..ctor.5tADfQ9q5nXUDj477SWvHg.md
new file mode 100644
index 00000000..ea3a5cb7
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock..ctor.5tADfQ9q5nXUDj477SWvHg.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock')
+
+## AzureBlobLeaseDistributedLock(BlobContainerClient, string, Action) Constructor
+
+Constructs a lock that will lease a blob based on [name](AzureBlobLeaseDistributedLock..ctor.5tADfQ9q5nXUDj477SWvHg.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobContainerClient,string,System.Action_Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder_).name 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobContainerClient, string, System.Action).name') within the provided [blobContainerClient](AzureBlobLeaseDistributedLock..ctor.5tADfQ9q5nXUDj477SWvHg.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobContainerClient,string,System.Action_Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder_).blobContainerClient 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobContainerClient, string, System.Action).blobContainerClient').
+
+```csharp
+public AzureBlobLeaseDistributedLock(BlobContainerClient blobContainerClient, string name, System.Action? options=null);
+```
+#### Parameters
+
+
+
+`blobContainerClient` [Azure.Storage.Blobs.BlobContainerClient](https://docs.microsoft.com/en-us/dotnet/api/Azure.Storage.Blobs.BlobContainerClient 'Azure.Storage.Blobs.BlobContainerClient')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`options` [System.Action<](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')[AzureBlobLeaseOptionsBuilder](AzureBlobLeaseOptionsBuilder.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock..ctor.PPb+8c/p7LTz4wSm4vPWGg.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock..ctor.PPb+8c/p7LTz4wSm4vPWGg.md
new file mode 100644
index 00000000..5f95b451
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock..ctor.PPb+8c/p7LTz4wSm4vPWGg.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock')
+
+## AzureBlobLeaseDistributedLock(BlobBaseClient, Action) Constructor
+
+Constructs a lock that will lease the provided [blobClient](AzureBlobLeaseDistributedLock..ctor.PPb+8c/p7LTz4wSm4vPWGg.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobBaseClient,System.Action_Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder_).blobClient 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobBaseClient, System.Action).blobClient')
+
+```csharp
+public AzureBlobLeaseDistributedLock(BlobBaseClient blobClient, System.Action? options=null);
+```
+#### Parameters
+
+
+
+`blobClient` [Azure.Storage.Blobs.Specialized.BlobBaseClient](https://docs.microsoft.com/en-us/dotnet/api/Azure.Storage.Blobs.Specialized.BlobBaseClient 'Azure.Storage.Blobs.Specialized.BlobBaseClient')
+
+
+
+`options` [System.Action<](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')[AzureBlobLeaseOptionsBuilder](AzureBlobLeaseOptionsBuilder.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.Acquire.jrwmxrsi+eqzAdB3xMnaMw.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.Acquire.jrwmxrsi+eqzAdB3xMnaMw.md
new file mode 100644
index 00000000..09dd930a
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.Acquire.jrwmxrsi+eqzAdB3xMnaMw.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock')
+
+## AzureBlobLeaseDistributedLock.Acquire(Nullable, CancellationToken) Method
+
+Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+using (myLock.Acquire(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle Acquire(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [Acquire(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md 'Medallion.Threading.IDistributedLock.Acquire(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle')
+An [AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.AcquireAsync.ulCFSvmk3VUn6f5ebzKW9A.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.AcquireAsync.ulCFSvmk3VUn6f5ebzKW9A.md
new file mode 100644
index 00000000..3b8bc5e6
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.AcquireAsync.ulCFSvmk3VUn6f5ebzKW9A.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock')
+
+## AzureBlobLeaseDistributedLock.AcquireAsync(Nullable, CancellationToken) Method
+
+Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+await using (await myLock.AcquireAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask AcquireAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md 'Medallion.Threading.IDistributedLock.AcquireAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.Name.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.Name.md
new file mode 100644
index 00000000..34eaa9c3
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.Name.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock')
+
+## AzureBlobLeaseDistributedLock.Name Property
+
+Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name')
+
+```csharp
+public string Name { get; }
+```
+
+Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name')
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.TryAcquire.1mh2rZwMkBLLsl/Ri/nDJA.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.TryAcquire.1mh2rZwMkBLLsl/Ri/nDJA.md
new file mode 100644
index 00000000..a9e82b02
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.TryAcquire.1mh2rZwMkBLLsl/Ri/nDJA.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock')
+
+## AzureBlobLeaseDistributedLock.TryAcquire(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock synchronously. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquire(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle? TryAcquire(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle')
+An [AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.TryAcquireAsync.h3ZvrsNxi9ZoUPGAFzUdCQ.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.TryAcquireAsync.h3ZvrsNxi9ZoUPGAFzUdCQ.md
new file mode 100644
index 00000000..83d5fd08
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.TryAcquireAsync.h3ZvrsNxi9ZoUPGAFzUdCQ.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock')
+
+## AzureBlobLeaseDistributedLock.TryAcquireAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock asynchronously. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask TryAcquireAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md 'Medallion.Threading.IDistributedLock.TryAcquireAsync(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.md
new file mode 100644
index 00000000..102f0c9d
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLock.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure')
+
+## AzureBlobLeaseDistributedLock Class
+
+Implements a [IDistributedLock](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.md 'Medallion.Threading.IDistributedLock') based on Azure blob leases
+
+```csharp
+public sealed class AzureBlobLeaseDistributedLock :
+Medallion.Threading.IDistributedLock
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 AzureBlobLeaseDistributedLock
+
+Implements [IDistributedLock](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.md 'Medallion.Threading.IDistributedLock')
+
+| Constructors | |
+| :--- | :--- |
+| [AzureBlobLeaseDistributedLock(BlobBaseClient, Action<AzureBlobLeaseOptionsBuilder>)](AzureBlobLeaseDistributedLock..ctor.PPb+8c/p7LTz4wSm4vPWGg.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobBaseClient, System.Action)') | Constructs a lock that will lease the provided [blobClient](AzureBlobLeaseDistributedLock..ctor.PPb+8c/p7LTz4wSm4vPWGg.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobBaseClient,System.Action_Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder_).blobClient 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobBaseClient, System.Action).blobClient') |
+| [AzureBlobLeaseDistributedLock(BlobContainerClient, string, Action<AzureBlobLeaseOptionsBuilder>)](AzureBlobLeaseDistributedLock..ctor.5tADfQ9q5nXUDj477SWvHg.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobContainerClient, string, System.Action)') | Constructs a lock that will lease a blob based on [name](AzureBlobLeaseDistributedLock..ctor.5tADfQ9q5nXUDj477SWvHg.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobContainerClient,string,System.Action_Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder_).name 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobContainerClient, string, System.Action).name') within the provided [blobContainerClient](AzureBlobLeaseDistributedLock..ctor.5tADfQ9q5nXUDj477SWvHg.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobContainerClient,string,System.Action_Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder_).blobContainerClient 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AzureBlobLeaseDistributedLock(BlobContainerClient, string, System.Action).blobContainerClient'). |
+
+| Properties | |
+| :--- | :--- |
+| [Name](AzureBlobLeaseDistributedLock.Name.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.Name') | Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name') |
+
+| Methods | |
+| :--- | :--- |
+| [Acquire(Nullable<TimeSpan>, CancellationToken)](AzureBlobLeaseDistributedLock.Acquire.jrwmxrsi+eqzAdB3xMnaMw.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.Acquire(System.Nullable, System.Threading.CancellationToken)') | Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](AzureBlobLeaseDistributedLock.AcquireAsync.ulCFSvmk3VUn6f5ebzKW9A.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.AcquireAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [TryAcquire(TimeSpan, CancellationToken)](AzureBlobLeaseDistributedLock.TryAcquire.1mh2rZwMkBLLsl/Ri/nDJA.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.TryAcquire(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire the lock synchronously. Usage: |
+| [TryAcquireAsync(TimeSpan, CancellationToken)](AzureBlobLeaseDistributedLock.TryAcquireAsync.h3ZvrsNxi9ZoUPGAFzUdCQ.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock.TryAcquireAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire the lock asynchronously. Usage: |
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.Dispose().md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.Dispose().md
new file mode 100644
index 00000000..0984c92d
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.Dispose().md
@@ -0,0 +1,12 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle')
+
+## AzureBlobLeaseDistributedLockHandle.Dispose() Method
+
+Releases the lock
+
+```csharp
+public void Dispose();
+```
+
+Implements [Dispose()](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable.Dispose 'System.IDisposable.Dispose')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.DisposeAsync().md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.DisposeAsync().md
new file mode 100644
index 00000000..7043c61e
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.DisposeAsync().md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle')
+
+## AzureBlobLeaseDistributedLockHandle.DisposeAsync() Method
+
+Releases the lock asynchronously
+
+```csharp
+public System.Threading.Tasks.ValueTask DisposeAsync();
+```
+
+Implements [DisposeAsync()](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable.DisposeAsync 'System.IAsyncDisposable.DisposeAsync')
+
+#### Returns
+[System.Threading.Tasks.ValueTask](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask 'System.Threading.Tasks.ValueTask')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.HandleLostToken.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.HandleLostToken.md
new file mode 100644
index 00000000..6c793b9b
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.HandleLostToken.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle')
+
+## AzureBlobLeaseDistributedLockHandle.HandleLostToken Property
+
+Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken')
+
+```csharp
+public System.Threading.CancellationToken HandleLostToken { get; }
+```
+
+Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken')
+
+#### Property Value
+[System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.LeaseId.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.LeaseId.md
new file mode 100644
index 00000000..db62f799
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.LeaseId.md
@@ -0,0 +1,13 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle')
+
+## AzureBlobLeaseDistributedLockHandle.LeaseId Property
+
+The underlying Azure lease ID
+
+```csharp
+public string LeaseId { get; }
+```
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.md
new file mode 100644
index 00000000..0b78077f
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedLockHandle.md
@@ -0,0 +1,27 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure')
+
+## AzureBlobLeaseDistributedLockHandle Class
+
+Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+
+```csharp
+public sealed class AzureBlobLeaseDistributedLockHandle :
+Medallion.Threading.IDistributedSynchronizationHandle,
+System.IDisposable,
+System.IAsyncDisposable
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 AzureBlobLeaseDistributedLockHandle
+
+Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle'), [System.IDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable 'System.IDisposable'), [System.IAsyncDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable 'System.IAsyncDisposable')
+
+| Properties | |
+| :--- | :--- |
+| [HandleLostToken](AzureBlobLeaseDistributedLockHandle.HandleLostToken.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle.HandleLostToken') | Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken') |
+| [LeaseId](AzureBlobLeaseDistributedLockHandle.LeaseId.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle.LeaseId') | The underlying Azure lease ID |
+
+| Methods | |
+| :--- | :--- |
+| [Dispose()](AzureBlobLeaseDistributedLockHandle.Dispose().md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle.Dispose()') | Releases the lock |
+| [DisposeAsync()](AzureBlobLeaseDistributedLockHandle.DisposeAsync().md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle.DisposeAsync()') | Releases the lock asynchronously |
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider..ctor.zZb9hLixHKXBbm4hZNaVyQ.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider..ctor.zZb9hLixHKXBbm4hZNaVyQ.md
new file mode 100644
index 00000000..62759c54
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider..ctor.zZb9hLixHKXBbm4hZNaVyQ.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedSynchronizationProvider](AzureBlobLeaseDistributedSynchronizationProvider.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider')
+
+## AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient, Action) Constructor
+
+Constructs a provider that scopes blobs within the provided [blobContainerClient](AzureBlobLeaseDistributedSynchronizationProvider..ctor.zZb9hLixHKXBbm4hZNaVyQ.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient,System.Action_Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder_).blobContainerClient 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient, System.Action).blobContainerClient') and uses the provided [options](AzureBlobLeaseDistributedSynchronizationProvider..ctor.zZb9hLixHKXBbm4hZNaVyQ.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient,System.Action_Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder_).options 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient, System.Action).options').
+
+```csharp
+public AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient blobContainerClient, System.Action? options=null);
+```
+#### Parameters
+
+
+
+`blobContainerClient` [Azure.Storage.Blobs.BlobContainerClient](https://docs.microsoft.com/en-us/dotnet/api/Azure.Storage.Blobs.BlobContainerClient 'Azure.Storage.Blobs.BlobContainerClient')
+
+
+
+`options` [System.Action<](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')[AzureBlobLeaseOptionsBuilder](AzureBlobLeaseOptionsBuilder.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider.CreateLock.I34EpC7k9lisV6FiK0xunw.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider.CreateLock.I34EpC7k9lisV6FiK0xunw.md
new file mode 100644
index 00000000..a3a27623
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider.CreateLock.I34EpC7k9lisV6FiK0xunw.md
@@ -0,0 +1,20 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseDistributedSynchronizationProvider](AzureBlobLeaseDistributedSynchronizationProvider.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider')
+
+## AzureBlobLeaseDistributedSynchronizationProvider.CreateLock(string) Method
+
+Constructs an [AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock') with the given [name](AzureBlobLeaseDistributedSynchronizationProvider.CreateLock.I34EpC7k9lisV6FiK0xunw.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.CreateLock(string).name 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.CreateLock(string).name').
+
+```csharp
+public Medallion.Threading.Azure.AzureBlobLeaseDistributedLock CreateLock(string name);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+Implements [CreateLock(string)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(System.String)')
+
+#### Returns
+[AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider.md
new file mode 100644
index 00000000..ecb59d71
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure')
+
+## AzureBlobLeaseDistributedSynchronizationProvider Class
+
+Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') for [AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock')
+
+```csharp
+public sealed class AzureBlobLeaseDistributedSynchronizationProvider :
+Medallion.Threading.IDistributedLockProvider
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 AzureBlobLeaseDistributedSynchronizationProvider
+
+Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider')
+
+| Constructors | |
+| :--- | :--- |
+| [AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient, Action<AzureBlobLeaseOptionsBuilder>)](AzureBlobLeaseDistributedSynchronizationProvider..ctor.zZb9hLixHKXBbm4hZNaVyQ.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient, System.Action)') | Constructs a provider that scopes blobs within the provided [blobContainerClient](AzureBlobLeaseDistributedSynchronizationProvider..ctor.zZb9hLixHKXBbm4hZNaVyQ.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient,System.Action_Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder_).blobContainerClient 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient, System.Action).blobContainerClient') and uses the provided [options](AzureBlobLeaseDistributedSynchronizationProvider..ctor.zZb9hLixHKXBbm4hZNaVyQ.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient,System.Action_Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder_).options 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient, System.Action).options'). |
+
+| Methods | |
+| :--- | :--- |
+| [CreateLock(string)](AzureBlobLeaseDistributedSynchronizationProvider.CreateLock.I34EpC7k9lisV6FiK0xunw.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.CreateLock(string)') | Constructs an [AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock') with the given [name](AzureBlobLeaseDistributedSynchronizationProvider.CreateLock.I34EpC7k9lisV6FiK0xunw.md#Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.CreateLock(string).name 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider.CreateLock(string).name'). |
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.BusyWaitSleepTime.mMUlB7vk6GdAQl9sAcmgNg.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.BusyWaitSleepTime.mMUlB7vk6GdAQl9sAcmgNg.md
new file mode 100644
index 00000000..b04ceb28
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.BusyWaitSleepTime.mMUlB7vk6GdAQl9sAcmgNg.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseOptionsBuilder](AzureBlobLeaseOptionsBuilder.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder')
+
+## AzureBlobLeaseOptionsBuilder.BusyWaitSleepTime(TimeSpan, TimeSpan) Method
+
+Waiting to acquire a lease requires a busy wait that alternates acquire attempts and sleeps.
+This determines how much time is spent sleeping between attempts. Lower values will raise the
+volume of acquire requests under contention but will also raise the responsiveness (how long
+it takes a waiter to notice that a contended the lease has become available).
+
+Specifying a range of values allows the implementation to select an actual value in the range
+at random for each sleep. This helps avoid the case where two clients become "synchronized"
+in such a way that results in one client monopolizing the lease.
+
+The default is [250ms, 1s]
+
+```csharp
+public Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder BusyWaitSleepTime(System.TimeSpan min, System.TimeSpan max);
+```
+#### Parameters
+
+
+
+`min` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`max` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+#### Returns
+[AzureBlobLeaseOptionsBuilder](AzureBlobLeaseOptionsBuilder.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.Duration.QEP6QPTxOgzkkg0h39jM/g.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.Duration.QEP6QPTxOgzkkg0h39jM/g.md
new file mode 100644
index 00000000..f2ebc9f5
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.Duration.QEP6QPTxOgzkkg0h39jM/g.md
@@ -0,0 +1,27 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseOptionsBuilder](AzureBlobLeaseOptionsBuilder.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder')
+
+## AzureBlobLeaseOptionsBuilder.Duration(TimeSpan) Method
+
+Specifies how long the lease will last, absent auto-renewal.
+
+If auto-renewal is enabled (the default), then a shorter duration means more frequent auto-renewal requests,
+while an infinite duration means no auto-renewal requests. Furthermore, if the lease-holding process were to
+exit without explicitly releasing, then duration determines how long other processes would need to wait in
+order to acquire the lease.
+
+If auto-renewal is disabled, then duration determines how long the lease will be held.
+
+Defaults to 30s.
+
+```csharp
+public Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder Duration(System.TimeSpan duration);
+```
+#### Parameters
+
+
+
+`duration` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+#### Returns
+[AzureBlobLeaseOptionsBuilder](AzureBlobLeaseOptionsBuilder.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.RenewalCadence/x+hnazpWWqAWeDDlrJmTg.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.RenewalCadence/x+hnazpWWqAWeDDlrJmTg.md
new file mode 100644
index 00000000..41f034da
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.RenewalCadence/x+hnazpWWqAWeDDlrJmTg.md
@@ -0,0 +1,24 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure').[AzureBlobLeaseOptionsBuilder](AzureBlobLeaseOptionsBuilder.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder')
+
+## AzureBlobLeaseOptionsBuilder.RenewalCadence(TimeSpan) Method
+
+Determines how frequently the lease will be renewed when held. More frequent renewal means more unnecessary requests
+but also a lower chance of losing the lease due to the process hanging or otherwise failing to get its renewal request in
+before the lease duration expires.
+
+To disable auto-renewal, specify [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+Defaults to 1/3 of the specified lease duration (may be infinite).
+
+```csharp
+public Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder RenewalCadence(System.TimeSpan renewalCadence);
+```
+#### Parameters
+
+
+
+`renewalCadence` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+#### Returns
+[AzureBlobLeaseOptionsBuilder](AzureBlobLeaseOptionsBuilder.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.md b/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.md
new file mode 100644
index 00000000..53623610
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/AzureBlobLeaseOptionsBuilder.md
@@ -0,0 +1,18 @@
+#### [DistributedLock.Azure](README.md 'README')
+### [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure')
+
+## AzureBlobLeaseOptionsBuilder Class
+
+Specifies options for an Azure blob lease
+
+```csharp
+public sealed class AzureBlobLeaseOptionsBuilder
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 AzureBlobLeaseOptionsBuilder
+
+| Methods | |
+| :--- | :--- |
+| [BusyWaitSleepTime(TimeSpan, TimeSpan)](AzureBlobLeaseOptionsBuilder.BusyWaitSleepTime.mMUlB7vk6GdAQl9sAcmgNg.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder.BusyWaitSleepTime(System.TimeSpan, System.TimeSpan)') | Waiting to acquire a lease requires a busy wait that alternates acquire attempts and sleeps. This determines how much time is spent sleeping between attempts. Lower values will raise the volume of acquire requests under contention but will also raise the responsiveness (how long it takes a waiter to notice that a contended the lease has become available). Specifying a range of values allows the implementation to select an actual value in the range at random for each sleep. This helps avoid the case where two clients become "synchronized" in such a way that results in one client monopolizing the lease. The default is [250ms, 1s] |
+| [Duration(TimeSpan)](AzureBlobLeaseOptionsBuilder.Duration.QEP6QPTxOgzkkg0h39jM/g.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder.Duration(System.TimeSpan)') | Specifies how long the lease will last, absent auto-renewal. If auto-renewal is enabled (the default), then a shorter duration means more frequent auto-renewal requests, while an infinite duration means no auto-renewal requests. Furthermore, if the lease-holding process were to exit without explicitly releasing, then duration determines how long other processes would need to wait in order to acquire the lease. If auto-renewal is disabled, then duration determines how long the lease will be held. Defaults to 30s. |
+| [RenewalCadence(TimeSpan)](AzureBlobLeaseOptionsBuilder.RenewalCadence./x+hnazpWWqAWeDDlrJmTg.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder.RenewalCadence(System.TimeSpan)') | Determines how frequently the lease will be renewed when held. More frequent renewal means more unnecessary requests but also a lower chance of losing the lease due to the process hanging or otherwise failing to get its renewal request in before the lease duration expires. To disable auto-renewal, specify [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan') Defaults to 1/3 of the specified lease duration (may be infinite). |
diff --git a/docs/api/DistributedLock.Azure/Medallion.Threading.Azure.md b/docs/api/DistributedLock.Azure/Medallion.Threading.Azure.md
new file mode 100644
index 00000000..01af2e9c
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/Medallion.Threading.Azure.md
@@ -0,0 +1,10 @@
+#### [DistributedLock.Azure](README.md 'README')
+
+## Medallion.Threading.Azure Namespace
+
+| Classes | |
+| :--- | :--- |
+| [AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock') | Implements a [IDistributedLock](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.md 'Medallion.Threading.IDistributedLock') based on Azure blob leases |
+| [AzureBlobLeaseDistributedLockHandle](AzureBlobLeaseDistributedLockHandle.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLockHandle') | Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') |
+| [AzureBlobLeaseDistributedSynchronizationProvider](AzureBlobLeaseDistributedSynchronizationProvider.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedSynchronizationProvider') | Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') for [AzureBlobLeaseDistributedLock](AzureBlobLeaseDistributedLock.md 'Medallion.Threading.Azure.AzureBlobLeaseDistributedLock') |
+| [AzureBlobLeaseOptionsBuilder](AzureBlobLeaseOptionsBuilder.md 'Medallion.Threading.Azure.AzureBlobLeaseOptionsBuilder') | Specifies options for an Azure blob lease |
diff --git a/docs/api/DistributedLock.Azure/README.md b/docs/api/DistributedLock.Azure/README.md
new file mode 100644
index 00000000..88cb1bf1
--- /dev/null
+++ b/docs/api/DistributedLock.Azure/README.md
@@ -0,0 +1,7 @@
+#### [DistributedLock.Azure](README.md 'README')
+
+## DistributedLock.Azure Assembly
+
+| Namespaces | |
+| :--- | :--- |
+| [Medallion.Threading.Azure](Medallion.Threading.Azure.md 'Medallion.Threading.Azure') | |
diff --git a/docs/api/DistributedLock.Core/DeadlockException..ctor.7kv3RcT81RlRFP35V3Vh0w.md b/docs/api/DistributedLock.Core/DeadlockException..ctor.7kv3RcT81RlRFP35V3Vh0w.md
new file mode 100644
index 00000000..ffc3d094
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DeadlockException..ctor.7kv3RcT81RlRFP35V3Vh0w.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DeadlockException](DeadlockException.md 'Medallion.Threading.DeadlockException')
+
+## DeadlockException(string, Exception) Constructor
+
+Constructs an instance of [DeadlockException](DeadlockException.md 'Medallion.Threading.DeadlockException') with the given [message](DeadlockException..ctor.7kv3RcT81RlRFP35V3Vh0w.md#Medallion.Threading.DeadlockException.DeadlockException(string,System.Exception).message 'Medallion.Threading.DeadlockException.DeadlockException(string, System.Exception).message') and [innerException](DeadlockException..ctor.7kv3RcT81RlRFP35V3Vh0w.md#Medallion.Threading.DeadlockException.DeadlockException(string,System.Exception).innerException 'Medallion.Threading.DeadlockException.DeadlockException(string, System.Exception).innerException')
+
+```csharp
+public DeadlockException(string message, System.Exception innerException);
+```
+#### Parameters
+
+
+
+`message` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`innerException` [System.Exception](https://docs.microsoft.com/en-us/dotnet/api/System.Exception 'System.Exception')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DeadlockException..ctor.rZAayxV0jwI4ZmlNNiyAyQ.md b/docs/api/DistributedLock.Core/DeadlockException..ctor.rZAayxV0jwI4ZmlNNiyAyQ.md
new file mode 100644
index 00000000..df577758
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DeadlockException..ctor.rZAayxV0jwI4ZmlNNiyAyQ.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DeadlockException](DeadlockException.md 'Medallion.Threading.DeadlockException')
+
+## DeadlockException(string) Constructor
+
+Constructs an instance of [DeadlockException](DeadlockException.md 'Medallion.Threading.DeadlockException') with the given [message](DeadlockException..ctor.rZAayxV0jwI4ZmlNNiyAyQ.md#Medallion.Threading.DeadlockException.DeadlockException(string).message 'Medallion.Threading.DeadlockException.DeadlockException(string).message')
+
+```csharp
+public DeadlockException(string message);
+```
+#### Parameters
+
+
+
+`message` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DeadlockException.DeadlockException().md b/docs/api/DistributedLock.Core/DeadlockException.DeadlockException().md
new file mode 100644
index 00000000..2c61a498
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DeadlockException.DeadlockException().md
@@ -0,0 +1,10 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DeadlockException](DeadlockException.md 'Medallion.Threading.DeadlockException')
+
+## DeadlockException() Constructor
+
+Constructs a new instance of [DeadlockException](DeadlockException.md 'Medallion.Threading.DeadlockException') with a default message
+
+```csharp
+public DeadlockException();
+```
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DeadlockException.md b/docs/api/DistributedLock.Core/DeadlockException.md
new file mode 100644
index 00000000..8b847a8b
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DeadlockException.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## DeadlockException Class
+
+An exception that SOME distributed locks will throw under SOME deadlock conditions. Note that even locks
+that throw this exception under some circumstances cannot detect ALL deadlock conditions
+
+```csharp
+public sealed class DeadlockException : System.InvalidOperationException
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 [System.Exception](https://docs.microsoft.com/en-us/dotnet/api/System.Exception 'System.Exception') 🡒 [System.SystemException](https://docs.microsoft.com/en-us/dotnet/api/System.SystemException 'System.SystemException') 🡒 [System.InvalidOperationException](https://docs.microsoft.com/en-us/dotnet/api/System.InvalidOperationException 'System.InvalidOperationException') 🡒 DeadlockException
+
+| Constructors | |
+| :--- | :--- |
+| [DeadlockException()](DeadlockException.DeadlockException().md 'Medallion.Threading.DeadlockException.DeadlockException()') | Constructs a new instance of [DeadlockException](DeadlockException.md 'Medallion.Threading.DeadlockException') with a default message |
+| [DeadlockException(string, Exception)](DeadlockException..ctor.7kv3RcT81RlRFP35V3Vh0w.md 'Medallion.Threading.DeadlockException.DeadlockException(string, System.Exception)') | Constructs an instance of [DeadlockException](DeadlockException.md 'Medallion.Threading.DeadlockException') with the given [message](DeadlockException..ctor.7kv3RcT81RlRFP35V3Vh0w.md#Medallion.Threading.DeadlockException.DeadlockException(string,System.Exception).message 'Medallion.Threading.DeadlockException.DeadlockException(string, System.Exception).message') and [innerException](DeadlockException..ctor.7kv3RcT81RlRFP35V3Vh0w.md#Medallion.Threading.DeadlockException.DeadlockException(string,System.Exception).innerException 'Medallion.Threading.DeadlockException.DeadlockException(string, System.Exception).innerException') |
+| [DeadlockException(string)](DeadlockException..ctor.rZAayxV0jwI4ZmlNNiyAyQ.md 'Medallion.Threading.DeadlockException.DeadlockException(string)') | Constructs an instance of [DeadlockException](DeadlockException.md 'Medallion.Threading.DeadlockException') with the given [message](DeadlockException..ctor.rZAayxV0jwI4ZmlNNiyAyQ.md#Medallion.Threading.DeadlockException.DeadlockException(string).message 'Medallion.Threading.DeadlockException.DeadlockException(string).message') |
diff --git a/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.AcquireLock.DMP8nUt70Bor8mi0Krb42A.md b/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.AcquireLock.DMP8nUt70Bor8mi0Krb42A.md
new file mode 100644
index 00000000..08b7a3e6
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.AcquireLock.DMP8nUt70Bor8mi0Krb42A.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedLockProviderExtensions](DistributedLockProviderExtensions.md 'Medallion.Threading.DistributedLockProviderExtensions')
+
+## DistributedLockProviderExtensions.AcquireLock(this IDistributedLockProvider, string, Nullable, CancellationToken) Method
+
+Equivalent to calling [CreateLock(string)](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(string)') and then
+[Acquire(Nullable<TimeSpan>, CancellationToken)](IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md 'Medallion.Threading.IDistributedLock.Acquire(System.Nullable, System.Threading.CancellationToken)').
+
+```csharp
+public static Medallion.Threading.IDistributedSynchronizationHandle AcquireLock(this Medallion.Threading.IDistributedLockProvider provider, string name, System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedLockProvider](IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.AcquireLockAsync.+REikXPbHJ/q+uAX8BwEjg.md b/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.AcquireLockAsync.+REikXPbHJ/q+uAX8BwEjg.md
new file mode 100644
index 00000000..bc8c4af5
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.AcquireLockAsync.+REikXPbHJ/q+uAX8BwEjg.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedLockProviderExtensions](DistributedLockProviderExtensions.md 'Medallion.Threading.DistributedLockProviderExtensions')
+
+## DistributedLockProviderExtensions.AcquireLockAsync(this IDistributedLockProvider, string, Nullable, CancellationToken) Method
+
+Equivalent to calling [CreateLock(string)](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(string)') and then
+[AcquireAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md 'Medallion.Threading.IDistributedLock.AcquireAsync(System.Nullable, System.Threading.CancellationToken)').
+
+```csharp
+public static System.Threading.Tasks.ValueTask AcquireLockAsync(this Medallion.Threading.IDistributedLockProvider provider, string name, System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedLockProvider](IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.TryAcquireLock.1sWD0pz+gM4NV17JJV3RTw.md b/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.TryAcquireLock.1sWD0pz+gM4NV17JJV3RTw.md
new file mode 100644
index 00000000..9821f0dd
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.TryAcquireLock.1sWD0pz+gM4NV17JJV3RTw.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedLockProviderExtensions](DistributedLockProviderExtensions.md 'Medallion.Threading.DistributedLockProviderExtensions')
+
+## DistributedLockProviderExtensions.TryAcquireLock(this IDistributedLockProvider, string, TimeSpan, CancellationToken) Method
+
+Equivalent to calling [CreateLock(string)](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(string)') and then
+[TryAcquire(TimeSpan, CancellationToken)](IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan, System.Threading.CancellationToken)').
+
+```csharp
+public static Medallion.Threading.IDistributedSynchronizationHandle? TryAcquireLock(this Medallion.Threading.IDistributedLockProvider provider, string name, System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedLockProvider](IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.TryAcquireLockAsync.eBA2EKzaS4eJOnnXosupQg.md b/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.TryAcquireLockAsync.eBA2EKzaS4eJOnnXosupQg.md
new file mode 100644
index 00000000..4c0f06bf
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.TryAcquireLockAsync.eBA2EKzaS4eJOnnXosupQg.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedLockProviderExtensions](DistributedLockProviderExtensions.md 'Medallion.Threading.DistributedLockProviderExtensions')
+
+## DistributedLockProviderExtensions.TryAcquireLockAsync(this IDistributedLockProvider, string, TimeSpan, CancellationToken) Method
+
+Equivalent to calling [CreateLock(string)](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(string)') and then
+[TryAcquireAsync(TimeSpan, CancellationToken)](IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md 'Medallion.Threading.IDistributedLock.TryAcquireAsync(System.TimeSpan, System.Threading.CancellationToken)').
+
+```csharp
+public static System.Threading.Tasks.ValueTask TryAcquireLockAsync(this Medallion.Threading.IDistributedLockProvider provider, string name, System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedLockProvider](IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.md b/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.md
new file mode 100644
index 00000000..068d9e7f
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedLockProviderExtensions.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## DistributedLockProviderExtensions Class
+
+Productivity helper methods for [IDistributedLockProvider](IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider')
+
+```csharp
+public static class DistributedLockProviderExtensions
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 DistributedLockProviderExtensions
+
+| Methods | |
+| :--- | :--- |
+| [AcquireLock(this IDistributedLockProvider, string, Nullable<TimeSpan>, CancellationToken)](DistributedLockProviderExtensions.AcquireLock.DMP8nUt70Bor8mi0Krb42A.md 'Medallion.Threading.DistributedLockProviderExtensions.AcquireLock(this Medallion.Threading.IDistributedLockProvider, string, System.Nullable, System.Threading.CancellationToken)') | Equivalent to calling [CreateLock(string)](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(string)') and then [Acquire(Nullable<TimeSpan>, CancellationToken)](IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md 'Medallion.Threading.IDistributedLock.Acquire(System.Nullable, System.Threading.CancellationToken)'). |
+| [AcquireLockAsync(this IDistributedLockProvider, string, Nullable<TimeSpan>, CancellationToken)](DistributedLockProviderExtensions.AcquireLockAsync.+REikXPbHJ/q+uAX8BwEjg.md 'Medallion.Threading.DistributedLockProviderExtensions.AcquireLockAsync(this Medallion.Threading.IDistributedLockProvider, string, System.Nullable, System.Threading.CancellationToken)') | Equivalent to calling [CreateLock(string)](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(string)') and then [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md 'Medallion.Threading.IDistributedLock.AcquireAsync(System.Nullable, System.Threading.CancellationToken)'). |
+| [TryAcquireLock(this IDistributedLockProvider, string, TimeSpan, CancellationToken)](DistributedLockProviderExtensions.TryAcquireLock.1sWD0pz+gM4NV17JJV3RTw.md 'Medallion.Threading.DistributedLockProviderExtensions.TryAcquireLock(this Medallion.Threading.IDistributedLockProvider, string, System.TimeSpan, System.Threading.CancellationToken)') | Equivalent to calling [CreateLock(string)](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(string)') and then [TryAcquire(TimeSpan, CancellationToken)](IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan, System.Threading.CancellationToken)'). |
+| [TryAcquireLockAsync(this IDistributedLockProvider, string, TimeSpan, CancellationToken)](DistributedLockProviderExtensions.TryAcquireLockAsync.eBA2EKzaS4eJOnnXosupQg.md 'Medallion.Threading.DistributedLockProviderExtensions.TryAcquireLockAsync(this Medallion.Threading.IDistributedLockProvider, string, System.TimeSpan, System.Threading.CancellationToken)') | Equivalent to calling [CreateLock(string)](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(string)') and then [TryAcquireAsync(TimeSpan, CancellationToken)](IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md 'Medallion.Threading.IDistributedLock.TryAcquireAsync(System.TimeSpan, System.Threading.CancellationToken)'). |
diff --git a/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireReadLock.ZhZPMV6nWYpiDzXAN3gDOQ.md b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireReadLock.ZhZPMV6nWYpiDzXAN3gDOQ.md
new file mode 100644
index 00000000..78230970
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireReadLock.ZhZPMV6nWYpiDzXAN3gDOQ.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedReaderWriterLockProviderExtensions](DistributedReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions')
+
+## DistributedReaderWriterLockProviderExtensions.AcquireReadLock(this IDistributedReaderWriterLockProvider, string, Nullable, CancellationToken) Method
+
+Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then
+[AcquireReadLock(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireReadLock.bAhgltfPpI+hi4bNotiyGg.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireReadLock(System.Nullable, System.Threading.CancellationToken)').
+
+```csharp
+public static Medallion.Threading.IDistributedSynchronizationHandle AcquireReadLock(this Medallion.Threading.IDistributedReaderWriterLockProvider provider, string name, System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireReadLockAsync.btqzvB7WyYZWa9xgYACZmA.md b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireReadLockAsync.btqzvB7WyYZWa9xgYACZmA.md
new file mode 100644
index 00000000..16eb057e
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireReadLockAsync.btqzvB7WyYZWa9xgYACZmA.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedReaderWriterLockProviderExtensions](DistributedReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions')
+
+## DistributedReaderWriterLockProviderExtensions.AcquireReadLockAsync(this IDistributedReaderWriterLockProvider, string, Nullable, CancellationToken) Method
+
+Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then
+[AcquireReadLockAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireReadLockAsync.otuQSEhQpAEqEEBnyFJHtw.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireReadLockAsync(System.Nullable, System.Threading.CancellationToken)').
+
+```csharp
+public static System.Threading.Tasks.ValueTask AcquireReadLockAsync(this Medallion.Threading.IDistributedReaderWriterLockProvider provider, string name, System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireWriteLock.KIDCaBOI+d5buraGWrnHpg.md b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireWriteLock.KIDCaBOI+d5buraGWrnHpg.md
new file mode 100644
index 00000000..cc5e86e4
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireWriteLock.KIDCaBOI+d5buraGWrnHpg.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedReaderWriterLockProviderExtensions](DistributedReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions')
+
+## DistributedReaderWriterLockProviderExtensions.AcquireWriteLock(this IDistributedReaderWriterLockProvider, string, Nullable, CancellationToken) Method
+
+Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then
+[AcquireWriteLock(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireWriteLock.8zDirrYDrgr0WzrsnH7blA.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireWriteLock(System.Nullable, System.Threading.CancellationToken)').
+
+```csharp
+public static Medallion.Threading.IDistributedSynchronizationHandle AcquireWriteLock(this Medallion.Threading.IDistributedReaderWriterLockProvider provider, string name, System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireWriteLockAsync.HT7LKAp7tqVtM/Vet3jdKQ.md b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireWriteLockAsync.HT7LKAp7tqVtM/Vet3jdKQ.md
new file mode 100644
index 00000000..40b19d56
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.AcquireWriteLockAsync.HT7LKAp7tqVtM/Vet3jdKQ.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedReaderWriterLockProviderExtensions](DistributedReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions')
+
+## DistributedReaderWriterLockProviderExtensions.AcquireWriteLockAsync(this IDistributedReaderWriterLockProvider, string, Nullable, CancellationToken) Method
+
+Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then
+[AcquireWriteLockAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireWriteLockAsync.fFyCc0HswQXUnGvjzNHJ+A.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireWriteLockAsync(System.Nullable, System.Threading.CancellationToken)').
+
+```csharp
+public static System.Threading.Tasks.ValueTask AcquireWriteLockAsync(this Medallion.Threading.IDistributedReaderWriterLockProvider provider, string name, System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireReadLock.vOCz3Wz2jkDdUYGywzVM8Q.md b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireReadLock.vOCz3Wz2jkDdUYGywzVM8Q.md
new file mode 100644
index 00000000..287c4518
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireReadLock.vOCz3Wz2jkDdUYGywzVM8Q.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedReaderWriterLockProviderExtensions](DistributedReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions')
+
+## DistributedReaderWriterLockProviderExtensions.TryAcquireReadLock(this IDistributedReaderWriterLockProvider, string, TimeSpan, CancellationToken) Method
+
+Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then
+[TryAcquireReadLock(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireReadLock.FwhFBAUmx9brWLKd6O1SSw.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireReadLock(System.TimeSpan, System.Threading.CancellationToken)').
+
+```csharp
+public static Medallion.Threading.IDistributedSynchronizationHandle? TryAcquireReadLock(this Medallion.Threading.IDistributedReaderWriterLockProvider provider, string name, System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireReadLockAsync.A1jgGtvBfzba5znceHCWSQ.md b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireReadLockAsync.A1jgGtvBfzba5znceHCWSQ.md
new file mode 100644
index 00000000..aa6b71a7
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireReadLockAsync.A1jgGtvBfzba5znceHCWSQ.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedReaderWriterLockProviderExtensions](DistributedReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions')
+
+## DistributedReaderWriterLockProviderExtensions.TryAcquireReadLockAsync(this IDistributedReaderWriterLockProvider, string, TimeSpan, CancellationToken) Method
+
+Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then
+[TryAcquireReadLockAsync(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireReadLockAsync.1wx2S+CeVe62/fKwnr3rNQ.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireReadLockAsync(System.TimeSpan, System.Threading.CancellationToken)').
+
+```csharp
+public static System.Threading.Tasks.ValueTask TryAcquireReadLockAsync(this Medallion.Threading.IDistributedReaderWriterLockProvider provider, string name, System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLock.JkEs48Kec6mXgXRDEw9ElQ.md b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLock.JkEs48Kec6mXgXRDEw9ElQ.md
new file mode 100644
index 00000000..11e8d150
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLock.JkEs48Kec6mXgXRDEw9ElQ.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedReaderWriterLockProviderExtensions](DistributedReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions')
+
+## DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLock(this IDistributedReaderWriterLockProvider, string, TimeSpan, CancellationToken) Method
+
+Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then
+[TryAcquireWriteLock(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireWriteLock.ypAYPzEP3B1U6LcOEQzWBw.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireWriteLock(System.TimeSpan, System.Threading.CancellationToken)').
+
+```csharp
+public static Medallion.Threading.IDistributedSynchronizationHandle? TryAcquireWriteLock(this Medallion.Threading.IDistributedReaderWriterLockProvider provider, string name, System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLockAsync.tsNArNTtLZ78uW3mRNiz0w.md b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLockAsync.tsNArNTtLZ78uW3mRNiz0w.md
new file mode 100644
index 00000000..5e98cd2e
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLockAsync.tsNArNTtLZ78uW3mRNiz0w.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedReaderWriterLockProviderExtensions](DistributedReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions')
+
+## DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLockAsync(this IDistributedReaderWriterLockProvider, string, TimeSpan, CancellationToken) Method
+
+Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then
+[TryAcquireWriteLockAsync(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireWriteLockAsync.yhTsitSwERpacPdxWmUvww.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireWriteLockAsync(System.TimeSpan, System.Threading.CancellationToken)').
+
+```csharp
+public static System.Threading.Tasks.ValueTask TryAcquireWriteLockAsync(this Medallion.Threading.IDistributedReaderWriterLockProvider provider, string name, System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.md b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.md
new file mode 100644
index 00000000..950422a2
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedReaderWriterLockProviderExtensions.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## DistributedReaderWriterLockProviderExtensions Class
+
+Productivity helper methods for [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+```csharp
+public static class DistributedReaderWriterLockProviderExtensions
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 DistributedReaderWriterLockProviderExtensions
+
+| Methods | |
+| :--- | :--- |
+| [AcquireReadLock(this IDistributedReaderWriterLockProvider, string, Nullable<TimeSpan>, CancellationToken)](DistributedReaderWriterLockProviderExtensions.AcquireReadLock.ZhZPMV6nWYpiDzXAN3gDOQ.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions.AcquireReadLock(this Medallion.Threading.IDistributedReaderWriterLockProvider, string, System.Nullable, System.Threading.CancellationToken)') | Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then [AcquireReadLock(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireReadLock.bAhgltfPpI+hi4bNotiyGg.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireReadLock(System.Nullable, System.Threading.CancellationToken)'). |
+| [AcquireReadLockAsync(this IDistributedReaderWriterLockProvider, string, Nullable<TimeSpan>, CancellationToken)](DistributedReaderWriterLockProviderExtensions.AcquireReadLockAsync.btqzvB7WyYZWa9xgYACZmA.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions.AcquireReadLockAsync(this Medallion.Threading.IDistributedReaderWriterLockProvider, string, System.Nullable, System.Threading.CancellationToken)') | Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then [AcquireReadLockAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireReadLockAsync.otuQSEhQpAEqEEBnyFJHtw.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireReadLockAsync(System.Nullable, System.Threading.CancellationToken)'). |
+| [AcquireWriteLock(this IDistributedReaderWriterLockProvider, string, Nullable<TimeSpan>, CancellationToken)](DistributedReaderWriterLockProviderExtensions.AcquireWriteLock.KIDCaBOI+d5buraGWrnHpg.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions.AcquireWriteLock(this Medallion.Threading.IDistributedReaderWriterLockProvider, string, System.Nullable, System.Threading.CancellationToken)') | Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then [AcquireWriteLock(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireWriteLock.8zDirrYDrgr0WzrsnH7blA.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireWriteLock(System.Nullable, System.Threading.CancellationToken)'). |
+| [AcquireWriteLockAsync(this IDistributedReaderWriterLockProvider, string, Nullable<TimeSpan>, CancellationToken)](DistributedReaderWriterLockProviderExtensions.AcquireWriteLockAsync.HT7LKAp7tqVtM/Vet3jdKQ.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions.AcquireWriteLockAsync(this Medallion.Threading.IDistributedReaderWriterLockProvider, string, System.Nullable, System.Threading.CancellationToken)') | Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then [AcquireWriteLockAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireWriteLockAsync.fFyCc0HswQXUnGvjzNHJ+A.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireWriteLockAsync(System.Nullable, System.Threading.CancellationToken)'). |
+| [TryAcquireReadLock(this IDistributedReaderWriterLockProvider, string, TimeSpan, CancellationToken)](DistributedReaderWriterLockProviderExtensions.TryAcquireReadLock.vOCz3Wz2jkDdUYGywzVM8Q.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions.TryAcquireReadLock(this Medallion.Threading.IDistributedReaderWriterLockProvider, string, System.TimeSpan, System.Threading.CancellationToken)') | Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then [TryAcquireReadLock(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireReadLock.FwhFBAUmx9brWLKd6O1SSw.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireReadLock(System.TimeSpan, System.Threading.CancellationToken)'). |
+| [TryAcquireReadLockAsync(this IDistributedReaderWriterLockProvider, string, TimeSpan, CancellationToken)](DistributedReaderWriterLockProviderExtensions.TryAcquireReadLockAsync.A1jgGtvBfzba5znceHCWSQ.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions.TryAcquireReadLockAsync(this Medallion.Threading.IDistributedReaderWriterLockProvider, string, System.TimeSpan, System.Threading.CancellationToken)') | Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then [TryAcquireReadLockAsync(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireReadLockAsync.1wx2S+CeVe62/fKwnr3rNQ.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireReadLockAsync(System.TimeSpan, System.Threading.CancellationToken)'). |
+| [TryAcquireWriteLock(this IDistributedReaderWriterLockProvider, string, TimeSpan, CancellationToken)](DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLock.JkEs48Kec6mXgXRDEw9ElQ.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLock(this Medallion.Threading.IDistributedReaderWriterLockProvider, string, System.TimeSpan, System.Threading.CancellationToken)') | Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then [TryAcquireWriteLock(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireWriteLock.ypAYPzEP3B1U6LcOEQzWBw.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireWriteLock(System.TimeSpan, System.Threading.CancellationToken)'). |
+| [TryAcquireWriteLockAsync(this IDistributedReaderWriterLockProvider, string, TimeSpan, CancellationToken)](DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLockAsync.tsNArNTtLZ78uW3mRNiz0w.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions.TryAcquireWriteLockAsync(this Medallion.Threading.IDistributedReaderWriterLockProvider, string, System.TimeSpan, System.Threading.CancellationToken)') | Equivalent to calling [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') and then [TryAcquireWriteLockAsync(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireWriteLockAsync.yhTsitSwERpacPdxWmUvww.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireWriteLockAsync(System.TimeSpan, System.Threading.CancellationToken)'). |
diff --git a/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.AcquireSemaphore.XSSUj7gKekS+ySxX0Ib0hA.md b/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.AcquireSemaphore.XSSUj7gKekS+ySxX0Ib0hA.md
new file mode 100644
index 00000000..81ab188d
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.AcquireSemaphore.XSSUj7gKekS+ySxX0Ib0hA.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedSemaphoreProviderExtensions](DistributedSemaphoreProviderExtensions.md 'Medallion.Threading.DistributedSemaphoreProviderExtensions')
+
+## DistributedSemaphoreProviderExtensions.AcquireSemaphore(this IDistributedSemaphoreProvider, string, int, Nullable, CancellationToken) Method
+
+Equivalent to calling [CreateSemaphore(string, int)](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int)') and then
+[Acquire(Nullable<TimeSpan>, CancellationToken)](IDistributedSemaphore.Acquire.Idy1BAzgGUWQ22QmqRZDsg.md 'Medallion.Threading.IDistributedSemaphore.Acquire(System.Nullable, System.Threading.CancellationToken)').
+
+```csharp
+public static Medallion.Threading.IDistributedSynchronizationHandle AcquireSemaphore(this Medallion.Threading.IDistributedSemaphoreProvider provider, string name, int maxCount, System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedSemaphoreProvider](IDistributedSemaphoreProvider.md 'Medallion.Threading.IDistributedSemaphoreProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`maxCount` [System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.AcquireSemaphoreAsync.lqwIyu+bS538c/gXNLgnKQ.md b/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.AcquireSemaphoreAsync.lqwIyu+bS538c/gXNLgnKQ.md
new file mode 100644
index 00000000..40d60b40
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.AcquireSemaphoreAsync.lqwIyu+bS538c/gXNLgnKQ.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedSemaphoreProviderExtensions](DistributedSemaphoreProviderExtensions.md 'Medallion.Threading.DistributedSemaphoreProviderExtensions')
+
+## DistributedSemaphoreProviderExtensions.AcquireSemaphoreAsync(this IDistributedSemaphoreProvider, string, int, Nullable, CancellationToken) Method
+
+Equivalent to calling [CreateSemaphore(string, int)](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int)') and then
+[AcquireAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedSemaphore.AcquireAsync.72hbd/OOOHUBoRAQHgD31Q.md 'Medallion.Threading.IDistributedSemaphore.AcquireAsync(System.Nullable, System.Threading.CancellationToken)').
+
+```csharp
+public static System.Threading.Tasks.ValueTask AcquireSemaphoreAsync(this Medallion.Threading.IDistributedSemaphoreProvider provider, string name, int maxCount, System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedSemaphoreProvider](IDistributedSemaphoreProvider.md 'Medallion.Threading.IDistributedSemaphoreProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`maxCount` [System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.TryAcquireSemaphore.Onb/urIfHteJZkfKKtFB7A.md b/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.TryAcquireSemaphore.Onb/urIfHteJZkfKKtFB7A.md
new file mode 100644
index 00000000..788b148c
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.TryAcquireSemaphore.Onb/urIfHteJZkfKKtFB7A.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedSemaphoreProviderExtensions](DistributedSemaphoreProviderExtensions.md 'Medallion.Threading.DistributedSemaphoreProviderExtensions')
+
+## DistributedSemaphoreProviderExtensions.TryAcquireSemaphore(this IDistributedSemaphoreProvider, string, int, TimeSpan, CancellationToken) Method
+
+Equivalent to calling [CreateSemaphore(string, int)](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int)') and then
+[TryAcquire(TimeSpan, CancellationToken)](IDistributedSemaphore.TryAcquire.G9QqgKI96XBtpNQoUp0RZg.md 'Medallion.Threading.IDistributedSemaphore.TryAcquire(System.TimeSpan, System.Threading.CancellationToken)').
+
+```csharp
+public static Medallion.Threading.IDistributedSynchronizationHandle? TryAcquireSemaphore(this Medallion.Threading.IDistributedSemaphoreProvider provider, string name, int maxCount, System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedSemaphoreProvider](IDistributedSemaphoreProvider.md 'Medallion.Threading.IDistributedSemaphoreProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`maxCount` [System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.TryAcquireSemaphoreAsync.4x4cCEwsrDjb1URUsaVDyg.md b/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.TryAcquireSemaphoreAsync.4x4cCEwsrDjb1URUsaVDyg.md
new file mode 100644
index 00000000..f3539dc9
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.TryAcquireSemaphoreAsync.4x4cCEwsrDjb1URUsaVDyg.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedSemaphoreProviderExtensions](DistributedSemaphoreProviderExtensions.md 'Medallion.Threading.DistributedSemaphoreProviderExtensions')
+
+## DistributedSemaphoreProviderExtensions.TryAcquireSemaphoreAsync(this IDistributedSemaphoreProvider, string, int, TimeSpan, CancellationToken) Method
+
+Equivalent to calling [CreateSemaphore(string, int)](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int)') and then
+[TryAcquireAsync(TimeSpan, CancellationToken)](IDistributedSemaphore.TryAcquireAsync.yTpJMeiQTyO40ByV0nmdkQ.md 'Medallion.Threading.IDistributedSemaphore.TryAcquireAsync(System.TimeSpan, System.Threading.CancellationToken)').
+
+```csharp
+public static System.Threading.Tasks.ValueTask TryAcquireSemaphoreAsync(this Medallion.Threading.IDistributedSemaphoreProvider provider, string name, int maxCount, System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedSemaphoreProvider](IDistributedSemaphoreProvider.md 'Medallion.Threading.IDistributedSemaphoreProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`maxCount` [System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.md b/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.md
new file mode 100644
index 00000000..1bb2535f
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedSemaphoreProviderExtensions.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## DistributedSemaphoreProviderExtensions Class
+
+Productivity helper methods for [IDistributedSemaphoreProvider](IDistributedSemaphoreProvider.md 'Medallion.Threading.IDistributedSemaphoreProvider')
+
+```csharp
+public static class DistributedSemaphoreProviderExtensions
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 DistributedSemaphoreProviderExtensions
+
+| Methods | |
+| :--- | :--- |
+| [AcquireSemaphore(this IDistributedSemaphoreProvider, string, int, Nullable<TimeSpan>, CancellationToken)](DistributedSemaphoreProviderExtensions.AcquireSemaphore.XSSUj7gKekS+ySxX0Ib0hA.md 'Medallion.Threading.DistributedSemaphoreProviderExtensions.AcquireSemaphore(this Medallion.Threading.IDistributedSemaphoreProvider, string, int, System.Nullable, System.Threading.CancellationToken)') | Equivalent to calling [CreateSemaphore(string, int)](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int)') and then [Acquire(Nullable<TimeSpan>, CancellationToken)](IDistributedSemaphore.Acquire.Idy1BAzgGUWQ22QmqRZDsg.md 'Medallion.Threading.IDistributedSemaphore.Acquire(System.Nullable, System.Threading.CancellationToken)'). |
+| [AcquireSemaphoreAsync(this IDistributedSemaphoreProvider, string, int, Nullable<TimeSpan>, CancellationToken)](DistributedSemaphoreProviderExtensions.AcquireSemaphoreAsync.lqwIyu+bS538c/gXNLgnKQ.md 'Medallion.Threading.DistributedSemaphoreProviderExtensions.AcquireSemaphoreAsync(this Medallion.Threading.IDistributedSemaphoreProvider, string, int, System.Nullable, System.Threading.CancellationToken)') | Equivalent to calling [CreateSemaphore(string, int)](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int)') and then [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedSemaphore.AcquireAsync.72hbd/OOOHUBoRAQHgD31Q.md 'Medallion.Threading.IDistributedSemaphore.AcquireAsync(System.Nullable, System.Threading.CancellationToken)'). |
+| [TryAcquireSemaphore(this IDistributedSemaphoreProvider, string, int, TimeSpan, CancellationToken)](DistributedSemaphoreProviderExtensions.TryAcquireSemaphore.Onb/urIfHteJZkfKKtFB7A.md 'Medallion.Threading.DistributedSemaphoreProviderExtensions.TryAcquireSemaphore(this Medallion.Threading.IDistributedSemaphoreProvider, string, int, System.TimeSpan, System.Threading.CancellationToken)') | Equivalent to calling [CreateSemaphore(string, int)](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int)') and then [TryAcquire(TimeSpan, CancellationToken)](IDistributedSemaphore.TryAcquire.G9QqgKI96XBtpNQoUp0RZg.md 'Medallion.Threading.IDistributedSemaphore.TryAcquire(System.TimeSpan, System.Threading.CancellationToken)'). |
+| [TryAcquireSemaphoreAsync(this IDistributedSemaphoreProvider, string, int, TimeSpan, CancellationToken)](DistributedSemaphoreProviderExtensions.TryAcquireSemaphoreAsync.4x4cCEwsrDjb1URUsaVDyg.md 'Medallion.Threading.DistributedSemaphoreProviderExtensions.TryAcquireSemaphoreAsync(this Medallion.Threading.IDistributedSemaphoreProvider, string, int, System.TimeSpan, System.Threading.CancellationToken)') | Equivalent to calling [CreateSemaphore(string, int)](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int)') and then [TryAcquireAsync(TimeSpan, CancellationToken)](IDistributedSemaphore.TryAcquireAsync.yTpJMeiQTyO40ByV0nmdkQ.md 'Medallion.Threading.IDistributedSemaphore.TryAcquireAsync(System.TimeSpan, System.Threading.CancellationToken)'). |
diff --git a/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLock.LhlQ1GjOVkQgN5H/PekFHw.md b/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLock.LhlQ1GjOVkQgN5H/PekFHw.md
new file mode 100644
index 00000000..cfffb1b0
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLock.LhlQ1GjOVkQgN5H/PekFHw.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedUpgradeableReaderWriterLockProviderExtensions](DistributedUpgradeableReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedUpgradeableReaderWriterLockProviderExtensions')
+
+## DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLock(this IDistributedUpgradeableReaderWriterLockProvider, string, Nullable, CancellationToken) Method
+
+Equivalent to calling [CreateUpgradeableReaderWriterLock(string)](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string)') and then
+[AcquireUpgradeableReadLock(Nullable<TimeSpan>, CancellationToken)](IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock.MgsbqNeNv0qen0RVQV8MHA.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock(System.Nullable, System.Threading.CancellationToken)').
+
+```csharp
+public static Medallion.Threading.IDistributedLockUpgradeableHandle AcquireUpgradeableReadLock(this Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider provider, string name, System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedUpgradeableReaderWriterLockProvider](IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLockAsync.ESXR5pVbQ3ZCoCNayGDOPQ.md b/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLockAsync.ESXR5pVbQ3ZCoCNayGDOPQ.md
new file mode 100644
index 00000000..861eb551
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLockAsync.ESXR5pVbQ3ZCoCNayGDOPQ.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedUpgradeableReaderWriterLockProviderExtensions](DistributedUpgradeableReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedUpgradeableReaderWriterLockProviderExtensions')
+
+## DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLockAsync(this IDistributedUpgradeableReaderWriterLockProvider, string, Nullable, CancellationToken) Method
+
+Equivalent to calling [CreateUpgradeableReaderWriterLock(string)](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string)') and then
+[AcquireUpgradeableReadLockAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync.XDD/LbfIJrScMNU14D5OvA.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync(System.Nullable, System.Threading.CancellationToken)').
+
+```csharp
+public static System.Threading.Tasks.ValueTask AcquireUpgradeableReadLockAsync(this Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider provider, string name, System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedUpgradeableReaderWriterLockProvider](IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLock.5Zr97IQvZb/lygC7zTxR2A.md b/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLock.5Zr97IQvZb/lygC7zTxR2A.md
new file mode 100644
index 00000000..67197ed3
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLock.5Zr97IQvZb/lygC7zTxR2A.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedUpgradeableReaderWriterLockProviderExtensions](DistributedUpgradeableReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedUpgradeableReaderWriterLockProviderExtensions')
+
+## DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLock(this IDistributedUpgradeableReaderWriterLockProvider, string, TimeSpan, CancellationToken) Method
+
+Equivalent to calling [CreateUpgradeableReaderWriterLock(string)](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string)') and then
+[TryAcquireUpgradeableReadLock(TimeSpan, CancellationToken)](IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock.NcomTiK4v4VsrD5p8zrY6A.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock(System.TimeSpan, System.Threading.CancellationToken)').
+
+```csharp
+public static Medallion.Threading.IDistributedLockUpgradeableHandle? TryAcquireUpgradeableReadLock(this Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider provider, string name, System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedUpgradeableReaderWriterLockProvider](IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLockAsync.xlsczpQ3Zsbfz74nI0lnPw.md b/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLockAsync.xlsczpQ3Zsbfz74nI0lnPw.md
new file mode 100644
index 00000000..f9852907
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLockAsync.xlsczpQ3Zsbfz74nI0lnPw.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[DistributedUpgradeableReaderWriterLockProviderExtensions](DistributedUpgradeableReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedUpgradeableReaderWriterLockProviderExtensions')
+
+## DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLockAsync(this IDistributedUpgradeableReaderWriterLockProvider, string, TimeSpan, CancellationToken) Method
+
+Equivalent to calling [CreateUpgradeableReaderWriterLock(string)](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string)') and then
+[TryAcquireUpgradeableReadLockAsync(TimeSpan, CancellationToken)](IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync.NeQQ4jMkCO0IteXQSJv/1w.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync(System.TimeSpan, System.Threading.CancellationToken)').
+
+```csharp
+public static System.Threading.Tasks.ValueTask TryAcquireUpgradeableReadLockAsync(this Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider provider, string name, System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`provider` [IDistributedUpgradeableReaderWriterLockProvider](IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.md b/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.md
new file mode 100644
index 00000000..fceed19a
--- /dev/null
+++ b/docs/api/DistributedLock.Core/DistributedUpgradeableReaderWriterLockProviderExtensions.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## DistributedUpgradeableReaderWriterLockProviderExtensions Class
+
+Productivity helper methods for [IDistributedUpgradeableReaderWriterLockProvider](IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider')
+
+```csharp
+public static class DistributedUpgradeableReaderWriterLockProviderExtensions
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 DistributedUpgradeableReaderWriterLockProviderExtensions
+
+| Methods | |
+| :--- | :--- |
+| [AcquireUpgradeableReadLock(this IDistributedUpgradeableReaderWriterLockProvider, string, Nullable<TimeSpan>, CancellationToken)](DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLock.LhlQ1GjOVkQgN5H/PekFHw.md 'Medallion.Threading.DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLock(this Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider, string, System.Nullable, System.Threading.CancellationToken)') | Equivalent to calling [CreateUpgradeableReaderWriterLock(string)](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string)') and then [AcquireUpgradeableReadLock(Nullable<TimeSpan>, CancellationToken)](IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock.MgsbqNeNv0qen0RVQV8MHA.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock(System.Nullable, System.Threading.CancellationToken)'). |
+| [AcquireUpgradeableReadLockAsync(this IDistributedUpgradeableReaderWriterLockProvider, string, Nullable<TimeSpan>, CancellationToken)](DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLockAsync.ESXR5pVbQ3ZCoCNayGDOPQ.md 'Medallion.Threading.DistributedUpgradeableReaderWriterLockProviderExtensions.AcquireUpgradeableReadLockAsync(this Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider, string, System.Nullable, System.Threading.CancellationToken)') | Equivalent to calling [CreateUpgradeableReaderWriterLock(string)](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string)') and then [AcquireUpgradeableReadLockAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync.XDD/LbfIJrScMNU14D5OvA.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync(System.Nullable, System.Threading.CancellationToken)'). |
+| [TryAcquireUpgradeableReadLock(this IDistributedUpgradeableReaderWriterLockProvider, string, TimeSpan, CancellationToken)](DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLock.5Zr97IQvZb/lygC7zTxR2A.md 'Medallion.Threading.DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLock(this Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider, string, System.TimeSpan, System.Threading.CancellationToken)') | Equivalent to calling [CreateUpgradeableReaderWriterLock(string)](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string)') and then [TryAcquireUpgradeableReadLock(TimeSpan, CancellationToken)](IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock.NcomTiK4v4VsrD5p8zrY6A.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock(System.TimeSpan, System.Threading.CancellationToken)'). |
+| [TryAcquireUpgradeableReadLockAsync(this IDistributedUpgradeableReaderWriterLockProvider, string, TimeSpan, CancellationToken)](DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLockAsync.xlsczpQ3Zsbfz74nI0lnPw.md 'Medallion.Threading.DistributedUpgradeableReaderWriterLockProviderExtensions.TryAcquireUpgradeableReadLockAsync(this Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider, string, System.TimeSpan, System.Threading.CancellationToken)') | Equivalent to calling [CreateUpgradeableReaderWriterLock(string)](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string)') and then [TryAcquireUpgradeableReadLockAsync(TimeSpan, CancellationToken)](IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync.NeQQ4jMkCO0IteXQSJv/1w.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync(System.TimeSpan, System.Threading.CancellationToken)'). |
diff --git a/docs/api/DistributedLock.Core/IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md b/docs/api/DistributedLock.Core/IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md
new file mode 100644
index 00000000..a1470380
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock')
+
+## IDistributedLock.Acquire(Nullable, CancellationToken) Method
+
+Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+using (myLock.Acquire(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+Medallion.Threading.IDistributedSynchronizationHandle Acquire(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md b/docs/api/DistributedLock.Core/IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md
new file mode 100644
index 00000000..f6381ffe
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock')
+
+## IDistributedLock.AcquireAsync(Nullable, CancellationToken) Method
+
+Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+await using (await myLock.AcquireAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+System.Threading.Tasks.ValueTask AcquireAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedLock.Name.md b/docs/api/DistributedLock.Core/IDistributedLock.Name.md
new file mode 100644
index 00000000..129e5da5
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLock.Name.md
@@ -0,0 +1,13 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock')
+
+## IDistributedLock.Name Property
+
+A name that uniquely identifies the lock
+
+```csharp
+string Name { get; }
+```
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md b/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md
new file mode 100644
index 00000000..4d93c450
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock')
+
+## IDistributedLock.TryAcquire(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock synchronously. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquire(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+Medallion.Threading.IDistributedSynchronizationHandle? TryAcquire(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md b/docs/api/DistributedLock.Core/IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md
new file mode 100644
index 00000000..442329e2
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock')
+
+## IDistributedLock.TryAcquireAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock asynchronously. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+System.Threading.Tasks.ValueTask TryAcquireAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedLock.md b/docs/api/DistributedLock.Core/IDistributedLock.md
new file mode 100644
index 00000000..b9dd3c83
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLock.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## IDistributedLock Interface
+
+A mutex synchronization primitive which can be used to coordinate access to a resource or critical region of code
+across processes or systems. The scope and capabilities of the lock are dependent on the particular implementation
+
+```csharp
+public interface IDistributedLock
+```
+
+| Properties | |
+| :--- | :--- |
+| [Name](IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name') | A name that uniquely identifies the lock |
+
+| Methods | |
+| :--- | :--- |
+| [Acquire(Nullable<TimeSpan>, CancellationToken)](IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md 'Medallion.Threading.IDistributedLock.Acquire(System.Nullable, System.Threading.CancellationToken)') | Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md 'Medallion.Threading.IDistributedLock.AcquireAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [TryAcquire(TimeSpan, CancellationToken)](IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire the lock synchronously. Usage: |
+| [TryAcquireAsync(TimeSpan, CancellationToken)](IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md 'Medallion.Threading.IDistributedLock.TryAcquireAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire the lock asynchronously. Usage: |
diff --git a/docs/api/DistributedLock.Core/IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md b/docs/api/DistributedLock.Core/IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md
new file mode 100644
index 00000000..ce7ad892
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md
@@ -0,0 +1,18 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedLockProvider](IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider')
+
+## IDistributedLockProvider.CreateLock(string) Method
+
+Constructs an [IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock') instance with the given [name](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md#Medallion.Threading.IDistributedLockProvider.CreateLock(string).name 'Medallion.Threading.IDistributedLockProvider.CreateLock(string).name').
+
+```csharp
+Medallion.Threading.IDistributedLock CreateLock(string name);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+#### Returns
+[IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedLockProvider.md b/docs/api/DistributedLock.Core/IDistributedLockProvider.md
new file mode 100644
index 00000000..8445e712
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLockProvider.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## IDistributedLockProvider Interface
+
+Acts as a factory for [IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock') instances of a certain type. This interface may be
+easier to use than [IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock') in dependency injection scenarios.
+
+```csharp
+public interface IDistributedLockProvider
+```
+
+| Methods | |
+| :--- | :--- |
+| [CreateLock(string)](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(string)') | Constructs an [IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock') instance with the given [name](IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md#Medallion.Threading.IDistributedLockProvider.CreateLock(string).name 'Medallion.Threading.IDistributedLockProvider.CreateLock(string).name'). |
diff --git a/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock.kj/tM1emIKPQTMhyxJaEVg.md b/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock.kj/tM1emIKPQTMhyxJaEVg.md
new file mode 100644
index 00000000..2238363a
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock.kj/tM1emIKPQTMhyxJaEVg.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')
+
+## IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock(TimeSpan, CancellationToken) Method
+
+Attempts to upgrade a WRITE lock synchronously. Not compatible with another WRITE lock or a UPGRADE lock
+
+```csharp
+bool TryUpgradeToWriteLock(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync.wN/ZfUBdRwlMtX9ctB9dtg.md b/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync.wN/ZfUBdRwlMtX9ctB9dtg.md
new file mode 100644
index 00000000..74643d87
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync.wN/ZfUBdRwlMtX9ctB9dtg.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')
+
+## IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync(TimeSpan, CancellationToken) Method
+
+Attempts to upgrade a WRITE lock asynchronously. Not compatible with another WRITE lock or a UPGRADE lock
+
+```csharp
+System.Threading.Tasks.ValueTask TryUpgradeToWriteLockAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLock.Tz7MsKLra+HymbjqGwuzRQ.md b/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLock.Tz7MsKLra+HymbjqGwuzRQ.md
new file mode 100644
index 00000000..50e7291b
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLock.Tz7MsKLra+HymbjqGwuzRQ.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')
+
+## IDistributedLockUpgradeableHandle.UpgradeToWriteLock(Nullable, CancellationToken) Method
+
+Upgrades to a WRITE lock synchronously. Not compatible with another WRITE lock or a UPGRADE lock
+
+```csharp
+void UpgradeToWriteLock(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync.5X2Faf/VtyA3b0uF1JN1kg.md b/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync.5X2Faf/VtyA3b0uF1JN1kg.md
new file mode 100644
index 00000000..a9674a1a
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync.5X2Faf/VtyA3b0uF1JN1kg.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')
+
+## IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync(Nullable, CancellationToken) Method
+
+Upgrades to a WRITE lock asynchronously. Not compatible with another WRITE lock or a UPGRADE lock
+
+```csharp
+System.Threading.Tasks.ValueTask UpgradeToWriteLockAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+#### Returns
+[System.Threading.Tasks.ValueTask](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask 'System.Threading.Tasks.ValueTask')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.md b/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.md
new file mode 100644
index 00000000..7080b127
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## IDistributedLockUpgradeableHandle Interface
+
+A [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') that can be upgraded to a write lock
+
+```csharp
+public interface IDistributedLockUpgradeableHandle :
+Medallion.Threading.IDistributedSynchronizationHandle,
+System.IDisposable,
+System.IAsyncDisposable
+```
+
+Implements [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle'), [System.IDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable 'System.IDisposable'), [System.IAsyncDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable 'System.IAsyncDisposable')
+
+| Methods | |
+| :--- | :--- |
+| [TryUpgradeToWriteLock(TimeSpan, CancellationToken)](IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock.kj/tM1emIKPQTMhyxJaEVg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to upgrade a WRITE lock synchronously. Not compatible with another WRITE lock or a UPGRADE lock |
+| [TryUpgradeToWriteLockAsync(TimeSpan, CancellationToken)](IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync.wN/ZfUBdRwlMtX9ctB9dtg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to upgrade a WRITE lock asynchronously. Not compatible with another WRITE lock or a UPGRADE lock |
+| [UpgradeToWriteLock(Nullable<TimeSpan>, CancellationToken)](IDistributedLockUpgradeableHandle.UpgradeToWriteLock.Tz7MsKLra+HymbjqGwuzRQ.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.UpgradeToWriteLock(System.Nullable, System.Threading.CancellationToken)') | Upgrades to a WRITE lock synchronously. Not compatible with another WRITE lock or a UPGRADE lock |
+| [UpgradeToWriteLockAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync.5X2Faf/VtyA3b0uF1JN1kg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync(System.Nullable, System.Threading.CancellationToken)') | Upgrades to a WRITE lock asynchronously. Not compatible with another WRITE lock or a UPGRADE lock |
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireReadLock.bAhgltfPpI+hi4bNotiyGg.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireReadLock.bAhgltfPpI+hi4bNotiyGg.md
new file mode 100644
index 00000000..b67a8b91
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireReadLock.bAhgltfPpI+hi4bNotiyGg.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+## IDistributedReaderWriterLock.AcquireReadLock(Nullable, CancellationToken) Method
+
+Acquires a READ lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Multiple readers are allowed. Not compatible with a WRITE lock. Usage:
+
+```csharp
+using (myLock.AcquireReadLock(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+Medallion.Threading.IDistributedSynchronizationHandle AcquireReadLock(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireReadLockAsync.otuQSEhQpAEqEEBnyFJHtw.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireReadLockAsync.otuQSEhQpAEqEEBnyFJHtw.md
new file mode 100644
index 00000000..2f2f1c75
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireReadLockAsync.otuQSEhQpAEqEEBnyFJHtw.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+## IDistributedReaderWriterLock.AcquireReadLockAsync(Nullable, CancellationToken) Method
+
+Acquires a READ lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Multiple readers are allowed. Not compatible with a WRITE lock. Usage:
+
+```csharp
+await using (await myLock.AcquireReadLockAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+System.Threading.Tasks.ValueTask AcquireReadLockAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireWriteLock.8zDirrYDrgr0WzrsnH7blA.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireWriteLock.8zDirrYDrgr0WzrsnH7blA.md
new file mode 100644
index 00000000..1907646f
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireWriteLock.8zDirrYDrgr0WzrsnH7blA.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+## IDistributedReaderWriterLock.AcquireWriteLock(Nullable, CancellationToken) Method
+
+Acquires a WRITE lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another WRITE lock or an UPGRADE lock. Usage:
+
+```csharp
+using (myLock.AcquireWriteLock(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+Medallion.Threading.IDistributedSynchronizationHandle AcquireWriteLock(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireWriteLockAsync.fFyCc0HswQXUnGvjzNHJ+A.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireWriteLockAsync.fFyCc0HswQXUnGvjzNHJ+A.md
new file mode 100644
index 00000000..22c33010
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireWriteLockAsync.fFyCc0HswQXUnGvjzNHJ+A.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+## IDistributedReaderWriterLock.AcquireWriteLockAsync(Nullable, CancellationToken) Method
+
+Acquires a WRITE lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another WRITE lock or an UPGRADE lock. Usage:
+
+```csharp
+await using (await myLock.AcquireWriteLockAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+System.Threading.Tasks.ValueTask AcquireWriteLockAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.Name.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.Name.md
new file mode 100644
index 00000000..7d99edda
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.Name.md
@@ -0,0 +1,13 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+## IDistributedReaderWriterLock.Name Property
+
+A name that uniquely identifies the lock
+
+```csharp
+string Name { get; }
+```
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireReadLock.FwhFBAUmx9brWLKd6O1SSw.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireReadLock.FwhFBAUmx9brWLKd6O1SSw.md
new file mode 100644
index 00000000..796e5819
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireReadLock.FwhFBAUmx9brWLKd6O1SSw.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+## IDistributedReaderWriterLock.TryAcquireReadLock(TimeSpan, CancellationToken) Method
+
+Attempts to acquire a READ lock synchronously. Multiple readers are allowed. Not compatible with a WRITE lock. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquireReadLock(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+Medallion.Threading.IDistributedSynchronizationHandle? TryAcquireReadLock(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireReadLockAsync.1wx2S+CeVe62/fKwnr3rNQ.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireReadLockAsync.1wx2S+CeVe62/fKwnr3rNQ.md
new file mode 100644
index 00000000..7eeaff05
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireReadLockAsync.1wx2S+CeVe62/fKwnr3rNQ.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+## IDistributedReaderWriterLock.TryAcquireReadLockAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire a READ lock asynchronously. Multiple readers are allowed. Not compatible with a WRITE lock. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireReadLockAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+System.Threading.Tasks.ValueTask TryAcquireReadLockAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireWriteLock.ypAYPzEP3B1U6LcOEQzWBw.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireWriteLock.ypAYPzEP3B1U6LcOEQzWBw.md
new file mode 100644
index 00000000..983dae31
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireWriteLock.ypAYPzEP3B1U6LcOEQzWBw.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+## IDistributedReaderWriterLock.TryAcquireWriteLock(TimeSpan, CancellationToken) Method
+
+Attempts to acquire a WRITE lock synchronously. Not compatible with another WRITE lock or an UPGRADE lock. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquireWriteLock(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+Medallion.Threading.IDistributedSynchronizationHandle? TryAcquireWriteLock(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireWriteLockAsync.yhTsitSwERpacPdxWmUvww.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireWriteLockAsync.yhTsitSwERpacPdxWmUvww.md
new file mode 100644
index 00000000..72c3eca9
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireWriteLockAsync.yhTsitSwERpacPdxWmUvww.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+## IDistributedReaderWriterLock.TryAcquireWriteLockAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire a WRITE lock asynchronously. Not compatible with another WRITE lock or an UPGRADE lock. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireWriteLockAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+System.Threading.Tasks.ValueTask TryAcquireWriteLockAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.md
new file mode 100644
index 00000000..ed747865
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.md
@@ -0,0 +1,28 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## IDistributedReaderWriterLock Interface
+
+Provides distributed locking functionality comparable to [System.Threading.ReaderWriterLock](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.ReaderWriterLock 'System.Threading.ReaderWriterLock')
+
+```csharp
+public interface IDistributedReaderWriterLock
+```
+
+Derived
+↳ [IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock')
+
+| Properties | |
+| :--- | :--- |
+| [Name](IDistributedReaderWriterLock.Name.md 'Medallion.Threading.IDistributedReaderWriterLock.Name') | A name that uniquely identifies the lock |
+
+| Methods | |
+| :--- | :--- |
+| [AcquireReadLock(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireReadLock.bAhgltfPpI+hi4bNotiyGg.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireReadLock(System.Nullable, System.Threading.CancellationToken)') | Acquires a READ lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Multiple readers are allowed. Not compatible with a WRITE lock. Usage: |
+| [AcquireReadLockAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireReadLockAsync.otuQSEhQpAEqEEBnyFJHtw.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireReadLockAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires a READ lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Multiple readers are allowed. Not compatible with a WRITE lock. Usage: |
+| [AcquireWriteLock(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireWriteLock.8zDirrYDrgr0WzrsnH7blA.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireWriteLock(System.Nullable, System.Threading.CancellationToken)') | Acquires a WRITE lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another WRITE lock or an UPGRADE lock. Usage: |
+| [AcquireWriteLockAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedReaderWriterLock.AcquireWriteLockAsync.fFyCc0HswQXUnGvjzNHJ+A.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireWriteLockAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires a WRITE lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another WRITE lock or an UPGRADE lock. Usage: |
+| [TryAcquireReadLock(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireReadLock.FwhFBAUmx9brWLKd6O1SSw.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireReadLock(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire a READ lock synchronously. Multiple readers are allowed. Not compatible with a WRITE lock. Usage: |
+| [TryAcquireReadLockAsync(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireReadLockAsync.1wx2S+CeVe62/fKwnr3rNQ.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireReadLockAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire a READ lock asynchronously. Multiple readers are allowed. Not compatible with a WRITE lock. Usage: |
+| [TryAcquireWriteLock(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireWriteLock.ypAYPzEP3B1U6LcOEQzWBw.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireWriteLock(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire a WRITE lock synchronously. Not compatible with another WRITE lock or an UPGRADE lock. Usage: |
+| [TryAcquireWriteLockAsync(TimeSpan, CancellationToken)](IDistributedReaderWriterLock.TryAcquireWriteLockAsync.yhTsitSwERpacPdxWmUvww.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireWriteLockAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire a WRITE lock asynchronously. Not compatible with another WRITE lock or an UPGRADE lock. Usage: |
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md
new file mode 100644
index 00000000..66bddf4c
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md
@@ -0,0 +1,18 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+## IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string) Method
+
+Constructs an [IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock') instance with the given [name](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md#Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string).name 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string).name').
+
+```csharp
+Medallion.Threading.IDistributedReaderWriterLock CreateReaderWriterLock(string name);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+#### Returns
+[IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedReaderWriterLockProvider.md b/docs/api/DistributedLock.Core/IDistributedReaderWriterLockProvider.md
new file mode 100644
index 00000000..53a2da6a
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedReaderWriterLockProvider.md
@@ -0,0 +1,18 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## IDistributedReaderWriterLockProvider Interface
+
+Acts as a factory for [IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock') instances of a certain type. This interface may be
+easier to use than [IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock') in dependency injection scenarios.
+
+```csharp
+public interface IDistributedReaderWriterLockProvider
+```
+
+Derived
+↳ [IDistributedUpgradeableReaderWriterLockProvider](IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider')
+
+| Methods | |
+| :--- | :--- |
+| [CreateReaderWriterLock(string)](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string)') | Constructs an [IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock') instance with the given [name](IDistributedReaderWriterLockProvider.CreateReaderWriterLock.BJyxJJllIyIqdlfqBHLDTA.md#Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string).name 'Medallion.Threading.IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string).name'). |
diff --git a/docs/api/DistributedLock.Core/IDistributedSemaphore.Acquire.Idy1BAzgGUWQ22QmqRZDsg.md b/docs/api/DistributedLock.Core/IDistributedSemaphore.Acquire.Idy1BAzgGUWQ22QmqRZDsg.md
new file mode 100644
index 00000000..cb376189
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSemaphore.Acquire.Idy1BAzgGUWQ22QmqRZDsg.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore')
+
+## IDistributedSemaphore.Acquire(Nullable, CancellationToken) Method
+
+Acquires a semaphore ticket synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+using (mySemaphore.Acquire(...))
+{
+ /* we have the ticket! */
+}
+// dispose releases the ticket
+```
+
+```csharp
+Medallion.Threading.IDistributedSynchronizationHandle Acquire(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the ticket
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedSemaphore.AcquireAsync.72hbd/OOOHUBoRAQHgD31Q.md b/docs/api/DistributedLock.Core/IDistributedSemaphore.AcquireAsync.72hbd/OOOHUBoRAQHgD31Q.md
new file mode 100644
index 00000000..0a84368c
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSemaphore.AcquireAsync.72hbd/OOOHUBoRAQHgD31Q.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore')
+
+## IDistributedSemaphore.AcquireAsync(Nullable, CancellationToken) Method
+
+Acquires a semaphore ticket asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+await using (await mySemaphore.AcquireAsync(...))
+{
+ /* we have the ticket! */
+}
+// dispose releases the ticket
+```
+
+```csharp
+System.Threading.Tasks.ValueTask AcquireAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the ticket
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedSemaphore.MaxCount.md b/docs/api/DistributedLock.Core/IDistributedSemaphore.MaxCount.md
new file mode 100644
index 00000000..52a0c243
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSemaphore.MaxCount.md
@@ -0,0 +1,14 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore')
+
+## IDistributedSemaphore.MaxCount Property
+
+The maximum number of "tickets" available for the semaphore (ie the number of processes which can acquire
+the semaphore concurrently).
+
+```csharp
+int MaxCount { get; }
+```
+
+#### Property Value
+[System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedSemaphore.Name.md b/docs/api/DistributedLock.Core/IDistributedSemaphore.Name.md
new file mode 100644
index 00000000..0709872c
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSemaphore.Name.md
@@ -0,0 +1,13 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore')
+
+## IDistributedSemaphore.Name Property
+
+A name that uniquely identifies the semaphore
+
+```csharp
+string Name { get; }
+```
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedSemaphore.TryAcquire.G9QqgKI96XBtpNQoUp0RZg.md b/docs/api/DistributedLock.Core/IDistributedSemaphore.TryAcquire.G9QqgKI96XBtpNQoUp0RZg.md
new file mode 100644
index 00000000..6c27ed12
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSemaphore.TryAcquire.G9QqgKI96XBtpNQoUp0RZg.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore')
+
+## IDistributedSemaphore.TryAcquire(TimeSpan, CancellationToken) Method
+
+Attempts to acquire a semaphore ticket synchronously. Usage:
+
+```csharp
+using (var handle = mySemaphore.TryAcquire(...))
+{
+ if (handle != null) { /* we have the ticket! */ }
+}
+// dispose releases the ticket if we took it
+```
+
+```csharp
+Medallion.Threading.IDistributedSynchronizationHandle? TryAcquire(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the ticket or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedSemaphore.TryAcquireAsync.yTpJMeiQTyO40ByV0nmdkQ.md b/docs/api/DistributedLock.Core/IDistributedSemaphore.TryAcquireAsync.yTpJMeiQTyO40ByV0nmdkQ.md
new file mode 100644
index 00000000..89da1802
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSemaphore.TryAcquireAsync.yTpJMeiQTyO40ByV0nmdkQ.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore')
+
+## IDistributedSemaphore.TryAcquireAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire a semaphore ticket asynchronously. Usage:
+
+```csharp
+await using (var handle = await mySemaphore.TryAcquireAsync(...))
+{
+ if (handle != null) { /* we have the ticket! */ }
+}
+// dispose releases the ticket if we took it
+```
+
+```csharp
+System.Threading.Tasks.ValueTask TryAcquireAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') which can be used to release the ticket or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedSemaphore.md b/docs/api/DistributedLock.Core/IDistributedSemaphore.md
new file mode 100644
index 00000000..9d1934a5
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSemaphore.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## IDistributedSemaphore Interface
+
+A synchronization primitive which restricts access to a resource or critical section of code to a fixed number of concurrent threads/processes.
+Compare to [System.Threading.Semaphore](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Semaphore 'System.Threading.Semaphore').
+
+```csharp
+public interface IDistributedSemaphore
+```
+
+| Properties | |
+| :--- | :--- |
+| [MaxCount](IDistributedSemaphore.MaxCount.md 'Medallion.Threading.IDistributedSemaphore.MaxCount') | The maximum number of "tickets" available for the semaphore (ie the number of processes which can acquire the semaphore concurrently). |
+| [Name](IDistributedSemaphore.Name.md 'Medallion.Threading.IDistributedSemaphore.Name') | A name that uniquely identifies the semaphore |
+
+| Methods | |
+| :--- | :--- |
+| [Acquire(Nullable<TimeSpan>, CancellationToken)](IDistributedSemaphore.Acquire.Idy1BAzgGUWQ22QmqRZDsg.md 'Medallion.Threading.IDistributedSemaphore.Acquire(System.Nullable, System.Threading.CancellationToken)') | Acquires a semaphore ticket synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedSemaphore.AcquireAsync.72hbd/OOOHUBoRAQHgD31Q.md 'Medallion.Threading.IDistributedSemaphore.AcquireAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires a semaphore ticket asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [TryAcquire(TimeSpan, CancellationToken)](IDistributedSemaphore.TryAcquire.G9QqgKI96XBtpNQoUp0RZg.md 'Medallion.Threading.IDistributedSemaphore.TryAcquire(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire a semaphore ticket synchronously. Usage: |
+| [TryAcquireAsync(TimeSpan, CancellationToken)](IDistributedSemaphore.TryAcquireAsync.yTpJMeiQTyO40ByV0nmdkQ.md 'Medallion.Threading.IDistributedSemaphore.TryAcquireAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire a semaphore ticket asynchronously. Usage: |
diff --git a/docs/api/DistributedLock.Core/IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md b/docs/api/DistributedLock.Core/IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md
new file mode 100644
index 00000000..c113d66c
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedSemaphoreProvider](IDistributedSemaphoreProvider.md 'Medallion.Threading.IDistributedSemaphoreProvider')
+
+## IDistributedSemaphoreProvider.CreateSemaphore(string, int) Method
+
+Constructs an [IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore') instance with the given [name](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md#Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string,int).name 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int).name').
+
+```csharp
+Medallion.Threading.IDistributedSemaphore CreateSemaphore(string name, int maxCount);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`maxCount` [System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
+
+#### Returns
+[IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedSemaphoreProvider.md b/docs/api/DistributedLock.Core/IDistributedSemaphoreProvider.md
new file mode 100644
index 00000000..c70aeeee
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSemaphoreProvider.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## IDistributedSemaphoreProvider Interface
+
+Acts as a factory for [IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore') instances of a certain type. This interface may be
+easier to use than [IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore') in dependency injection scenarios.
+
+```csharp
+public interface IDistributedSemaphoreProvider
+```
+
+| Methods | |
+| :--- | :--- |
+| [CreateSemaphore(string, int)](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int)') | Constructs an [IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore') instance with the given [name](IDistributedSemaphoreProvider.CreateSemaphore.AA9FahTKczyqDQd0GIAGzQ.md#Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string,int).name 'Medallion.Threading.IDistributedSemaphoreProvider.CreateSemaphore(string, int).name'). |
diff --git a/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md b/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md
new file mode 100644
index 00000000..b3d94fce
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md
@@ -0,0 +1,24 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+
+## IDistributedSynchronizationHandle.HandleLostToken Property
+
+Gets a [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken') instance which may be used to
+monitor whether the handle to the lock is lost before the handle is
+disposed.
+
+For example, this could happen if the lock is backed by a
+database and the connection to the database is disrupted.
+
+Not all lock types support this; those that don't will return [System.Threading.CancellationToken.None](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken.None 'System.Threading.CancellationToken.None')
+which can be detected by checking [System.Threading.CancellationToken.CanBeCanceled](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken.CanBeCanceled 'System.Threading.CancellationToken.CanBeCanceled').
+
+For lock types that do support this, accessing this property may incur additional
+costs, such as polling to detect connectivity loss.
+
+```csharp
+System.Threading.CancellationToken HandleLostToken { get; }
+```
+
+#### Property Value
+[System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md b/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md
new file mode 100644
index 00000000..953923e2
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## IDistributedSynchronizationHandle Interface
+
+A handle to a distributed lock or other synchronization primitive. To unlock/release,
+simply dispose the handle.
+
+```csharp
+public interface IDistributedSynchronizationHandle :
+System.IDisposable,
+System.IAsyncDisposable
+```
+
+Derived
+↳ [IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')
+
+Implements [System.IDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable 'System.IDisposable'), [System.IAsyncDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable 'System.IAsyncDisposable')
+
+| Properties | |
+| :--- | :--- |
+| [HandleLostToken](IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken') | Gets a [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken') instance which may be used to monitor whether the handle to the lock is lost before the handle is disposed. For example, this could happen if the lock is backed by a database and the connection to the database is disrupted. Not all lock types support this; those that don't will return [System.Threading.CancellationToken.None](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken.None 'System.Threading.CancellationToken.None') which can be detected by checking [System.Threading.CancellationToken.CanBeCanceled](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken.CanBeCanceled 'System.Threading.CancellationToken.CanBeCanceled'). For lock types that do support this, accessing this property may incur additional costs, such as polling to detect connectivity loss. |
diff --git a/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock.MgsbqNeNv0qen0RVQV8MHA.md b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock.MgsbqNeNv0qen0RVQV8MHA.md
new file mode 100644
index 00000000..864e1194
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock.MgsbqNeNv0qen0RVQV8MHA.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock')
+
+## IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock(Nullable, CancellationToken) Method
+
+Acquires an UPGRADE lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another UPGRADE lock or a WRITE lock. Usage:
+
+```csharp
+using (myLock.AcquireUpgradeableReadLock(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+Medallion.Threading.IDistributedLockUpgradeableHandle AcquireUpgradeableReadLock(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')
+An [IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync.XDD/LbfIJrScMNU14D5OvA.md b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync.XDD/LbfIJrScMNU14D5OvA.md
new file mode 100644
index 00000000..e001e754
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync.XDD/LbfIJrScMNU14D5OvA.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock')
+
+## IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync(Nullable, CancellationToken) Method
+
+Acquires an UPGRADE lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another UPGRADE lock or a WRITE lock. Usage:
+
+```csharp
+await using (await myLock.AcquireUpgradeableReadLockAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+System.Threading.Tasks.ValueTask AcquireUpgradeableReadLockAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock.NcomTiK4v4VsrD5p8zrY6A.md b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock.NcomTiK4v4VsrD5p8zrY6A.md
new file mode 100644
index 00000000..28659989
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock.NcomTiK4v4VsrD5p8zrY6A.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock')
+
+## IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock(TimeSpan, CancellationToken) Method
+
+Attempts to acquire an UPGRADE lock synchronously. Not compatible with another UPGRADE lock or a WRITE lock. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquireUpgradeableReadLock(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+Medallion.Threading.IDistributedLockUpgradeableHandle? TryAcquireUpgradeableReadLock(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')
+An [IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync.NeQQ4jMkCO0IteXQSJv/1w.md b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync.NeQQ4jMkCO0IteXQSJv/1w.md
new file mode 100644
index 00000000..1793a755
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync.NeQQ4jMkCO0IteXQSJv/1w.md
@@ -0,0 +1,35 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock')
+
+## IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire an UPGRADE lock asynchronously. Not compatible with another UPGRADE lock or a WRITE lock. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireUpgradeableReadLockAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+System.Threading.Tasks.ValueTask TryAcquireUpgradeableReadLockAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.md b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.md
new file mode 100644
index 00000000..b62695d4
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## IDistributedUpgradeableReaderWriterLock Interface
+
+Extends [IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock') with the ability to take an "upgrade" lock. Like a read lock, an upgrade lock
+allows for other concurrent read locks, but not for other upgrade or write locks. However, an upgrade lock can also be upgraded to a write
+lock without releasing the underlying handle.
+
+```csharp
+public interface IDistributedUpgradeableReaderWriterLock :
+Medallion.Threading.IDistributedReaderWriterLock
+```
+
+Implements [IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+| Methods | |
+| :--- | :--- |
+| [AcquireUpgradeableReadLock(Nullable<TimeSpan>, CancellationToken)](IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock.MgsbqNeNv0qen0RVQV8MHA.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock(System.Nullable, System.Threading.CancellationToken)') | Acquires an UPGRADE lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another UPGRADE lock or a WRITE lock. Usage: |
+| [AcquireUpgradeableReadLockAsync(Nullable<TimeSpan>, CancellationToken)](IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync.XDD/LbfIJrScMNU14D5OvA.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires an UPGRADE lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another UPGRADE lock or a WRITE lock. Usage: |
+| [TryAcquireUpgradeableReadLock(TimeSpan, CancellationToken)](IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock.NcomTiK4v4VsrD5p8zrY6A.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire an UPGRADE lock synchronously. Not compatible with another UPGRADE lock or a WRITE lock. Usage: |
+| [TryAcquireUpgradeableReadLockAsync(TimeSpan, CancellationToken)](IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync.NeQQ4jMkCO0IteXQSJv/1w.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire an UPGRADE lock asynchronously. Not compatible with another UPGRADE lock or a WRITE lock. Usage: |
diff --git a/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md
new file mode 100644
index 00000000..17e743e2
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md
@@ -0,0 +1,18 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading').[IDistributedUpgradeableReaderWriterLockProvider](IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider')
+
+## IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string) Method
+
+Constructs an [IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock') instance with the given [name](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md#Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string).name 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string).name').
+
+```csharp
+Medallion.Threading.IDistributedUpgradeableReaderWriterLock CreateUpgradeableReaderWriterLock(string name);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+#### Returns
+[IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLockProvider.md b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLockProvider.md
new file mode 100644
index 00000000..7ac98370
--- /dev/null
+++ b/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLockProvider.md
@@ -0,0 +1,18 @@
+#### [DistributedLock.Core](README.md 'README')
+### [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading')
+
+## IDistributedUpgradeableReaderWriterLockProvider Interface
+
+Acts as a factory for [IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock') instances of a certain type. This interface may be
+easier to use than [IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock') in dependency injection scenarios.
+
+```csharp
+public interface IDistributedUpgradeableReaderWriterLockProvider :
+Medallion.Threading.IDistributedReaderWriterLockProvider
+```
+
+Implements [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+| Methods | |
+| :--- | :--- |
+| [CreateUpgradeableReaderWriterLock(string)](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string)') | Constructs an [IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock') instance with the given [name](IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock.CLmVtTtcnh6LtTDHkHXXtQ.md#Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string).name 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider.CreateUpgradeableReaderWriterLock(string).name'). |
diff --git a/docs/api/DistributedLock.Core/Medallion.Threading.md b/docs/api/DistributedLock.Core/Medallion.Threading.md
new file mode 100644
index 00000000..fd812818
--- /dev/null
+++ b/docs/api/DistributedLock.Core/Medallion.Threading.md
@@ -0,0 +1,24 @@
+#### [DistributedLock.Core](README.md 'README')
+
+## Medallion.Threading Namespace
+
+| Classes | |
+| :--- | :--- |
+| [DeadlockException](DeadlockException.md 'Medallion.Threading.DeadlockException') | An exception that SOME distributed locks will throw under SOME deadlock conditions. Note that even locks that throw this exception under some circumstances cannot detect ALL deadlock conditions |
+| [DistributedLockProviderExtensions](DistributedLockProviderExtensions.md 'Medallion.Threading.DistributedLockProviderExtensions') | Productivity helper methods for [IDistributedLockProvider](IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') |
+| [DistributedReaderWriterLockProviderExtensions](DistributedReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedReaderWriterLockProviderExtensions') | Productivity helper methods for [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider') |
+| [DistributedSemaphoreProviderExtensions](DistributedSemaphoreProviderExtensions.md 'Medallion.Threading.DistributedSemaphoreProviderExtensions') | Productivity helper methods for [IDistributedSemaphoreProvider](IDistributedSemaphoreProvider.md 'Medallion.Threading.IDistributedSemaphoreProvider') |
+| [DistributedUpgradeableReaderWriterLockProviderExtensions](DistributedUpgradeableReaderWriterLockProviderExtensions.md 'Medallion.Threading.DistributedUpgradeableReaderWriterLockProviderExtensions') | Productivity helper methods for [IDistributedUpgradeableReaderWriterLockProvider](IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider') |
+
+| Interfaces | |
+| :--- | :--- |
+| [IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock') | A mutex synchronization primitive which can be used to coordinate access to a resource or critical region of code across processes or systems. The scope and capabilities of the lock are dependent on the particular implementation |
+| [IDistributedLockProvider](IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') | Acts as a factory for [IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock') instances of a certain type. This interface may be easier to use than [IDistributedLock](IDistributedLock.md 'Medallion.Threading.IDistributedLock') in dependency injection scenarios. |
+| [IDistributedLockUpgradeableHandle](IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle') | A [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') that can be upgraded to a write lock |
+| [IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock') | Provides distributed locking functionality comparable to [System.Threading.ReaderWriterLock](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.ReaderWriterLock 'System.Threading.ReaderWriterLock') |
+| [IDistributedReaderWriterLockProvider](IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider') | Acts as a factory for [IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock') instances of a certain type. This interface may be easier to use than [IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock') in dependency injection scenarios. |
+| [IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore') | A synchronization primitive which restricts access to a resource or critical section of code to a fixed number of concurrent threads/processes. Compare to [System.Threading.Semaphore](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Semaphore 'System.Threading.Semaphore'). |
+| [IDistributedSemaphoreProvider](IDistributedSemaphoreProvider.md 'Medallion.Threading.IDistributedSemaphoreProvider') | Acts as a factory for [IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore') instances of a certain type. This interface may be easier to use than [IDistributedSemaphore](IDistributedSemaphore.md 'Medallion.Threading.IDistributedSemaphore') in dependency injection scenarios. |
+| [IDistributedSynchronizationHandle](IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') | A handle to a distributed lock or other synchronization primitive. To unlock/release, simply dispose the handle. |
+| [IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock') | Extends [IDistributedReaderWriterLock](IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock') with the ability to take an "upgrade" lock. Like a read lock, an upgrade lock allows for other concurrent read locks, but not for other upgrade or write locks. However, an upgrade lock can also be upgraded to a write lock without releasing the underlying handle. |
+| [IDistributedUpgradeableReaderWriterLockProvider](IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider') | Acts as a factory for [IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock') instances of a certain type. This interface may be easier to use than [IDistributedUpgradeableReaderWriterLock](IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock') in dependency injection scenarios. |
diff --git a/docs/api/DistributedLock.Core/README.md b/docs/api/DistributedLock.Core/README.md
new file mode 100644
index 00000000..21c48135
--- /dev/null
+++ b/docs/api/DistributedLock.Core/README.md
@@ -0,0 +1,9 @@
+#### [DistributedLock.Core](README.md 'README')
+
+## DistributedLock.Core Assembly
+
+DistributedLock.Core is such a cool library!
+
+| Namespaces | |
+| :--- | :--- |
+| [Medallion.Threading](Medallion.Threading.md 'Medallion.Threading') | |
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLock..ctor.vNzzxMsPVMiUjD+hEvX7EQ.md b/docs/api/DistributedLock.FileSystem/FileDistributedLock..ctor.vNzzxMsPVMiUjD+hEvX7EQ.md
new file mode 100644
index 00000000..1fa23f63
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLock..ctor.vNzzxMsPVMiUjD+hEvX7EQ.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock')
+
+## FileDistributedLock(DirectoryInfo, string) Constructor
+
+Constructs a lock which will place a lock file in [lockFileDirectory](FileDistributedLock..ctor.vNzzxMsPVMiUjD+hEvX7EQ.md#Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.DirectoryInfo,string).lockFileDirectory 'Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.DirectoryInfo, string).lockFileDirectory'). The file's name
+will be based on [name](FileDistributedLock..ctor.vNzzxMsPVMiUjD+hEvX7EQ.md#Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.DirectoryInfo,string).name 'Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.DirectoryInfo, string).name'), but with proper escaping/hashing to ensure that a valid file name is produced.
+
+Upon acquiring the lock, the file's directory will be created automatically if it does not already exist. The file
+will similarly be created if it does not already exist, and will be deleted when the lock is released.
+
+```csharp
+public FileDistributedLock(System.IO.DirectoryInfo lockFileDirectory, string name);
+```
+#### Parameters
+
+
+
+`lockFileDirectory` [System.IO.DirectoryInfo](https://docs.microsoft.com/en-us/dotnet/api/System.IO.DirectoryInfo 'System.IO.DirectoryInfo')
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLock..ctor/N7mTMuqXSs9QBL49fhQcQ.md b/docs/api/DistributedLock.FileSystem/FileDistributedLock..ctor/N7mTMuqXSs9QBL49fhQcQ.md
new file mode 100644
index 00000000..5c5c249d
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLock..ctor/N7mTMuqXSs9QBL49fhQcQ.md
@@ -0,0 +1,18 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock')
+
+## FileDistributedLock(FileInfo) Constructor
+
+Constructs a lock which uses the provided [lockFile](FileDistributedLock..ctor./N7mTMuqXSs9QBL49fhQcQ.md#Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.FileInfo).lockFile 'Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.FileInfo).lockFile') as the exact file name.
+
+Upon acquiring the lock, the file's directory will be created automatically if it does not already exist. The file
+will similarly be created if it does not already exist, and will be deleted when the lock is released.
+
+```csharp
+public FileDistributedLock(System.IO.FileInfo lockFile);
+```
+#### Parameters
+
+
+
+`lockFile` [System.IO.FileInfo](https://docs.microsoft.com/en-us/dotnet/api/System.IO.FileInfo 'System.IO.FileInfo')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLock.Acquire.Cxe4kn5Dotos0VNT8S7mFg.md b/docs/api/DistributedLock.FileSystem/FileDistributedLock.Acquire.Cxe4kn5Dotos0VNT8S7mFg.md
new file mode 100644
index 00000000..97e7755d
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLock.Acquire.Cxe4kn5Dotos0VNT8S7mFg.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock')
+
+## FileDistributedLock.Acquire(Nullable, CancellationToken) Method
+
+Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+using (myLock.Acquire(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public Medallion.Threading.FileSystem.FileDistributedLockHandle Acquire(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [Acquire(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md 'Medallion.Threading.IDistributedLock.Acquire(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle')
+A [FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLock.AcquireAsync.S5lCsEuKHmzK+f7lUXq+aw.md b/docs/api/DistributedLock.FileSystem/FileDistributedLock.AcquireAsync.S5lCsEuKHmzK+f7lUXq+aw.md
new file mode 100644
index 00000000..c8b8f844
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLock.AcquireAsync.S5lCsEuKHmzK+f7lUXq+aw.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock')
+
+## FileDistributedLock.AcquireAsync(Nullable, CancellationToken) Method
+
+Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+await using (await myLock.AcquireAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask AcquireAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md 'Medallion.Threading.IDistributedLock.AcquireAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+A [FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLock.Name.md b/docs/api/DistributedLock.FileSystem/FileDistributedLock.Name.md
new file mode 100644
index 00000000..ed0fa14f
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLock.Name.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock')
+
+## FileDistributedLock.Name Property
+
+Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name')
+
+```csharp
+public string Name { get; }
+```
+
+Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name')
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLock.TryAcquire.zN8fZOiOkhzpcu5NxeJk8g.md b/docs/api/DistributedLock.FileSystem/FileDistributedLock.TryAcquire.zN8fZOiOkhzpcu5NxeJk8g.md
new file mode 100644
index 00000000..3b9eac62
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLock.TryAcquire.zN8fZOiOkhzpcu5NxeJk8g.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock')
+
+## FileDistributedLock.TryAcquire(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock synchronously. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquire(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public Medallion.Threading.FileSystem.FileDistributedLockHandle? TryAcquire(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle')
+A [FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLock.TryAcquireAsync.VuLjCVM0f9HO9kvR8wPWxQ.md b/docs/api/DistributedLock.FileSystem/FileDistributedLock.TryAcquireAsync.VuLjCVM0f9HO9kvR8wPWxQ.md
new file mode 100644
index 00000000..5e850fbd
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLock.TryAcquireAsync.VuLjCVM0f9HO9kvR8wPWxQ.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock')
+
+## FileDistributedLock.TryAcquireAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock asynchronously. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask TryAcquireAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md 'Medallion.Threading.IDistributedLock.TryAcquireAsync(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+A [FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLock.md b/docs/api/DistributedLock.FileSystem/FileDistributedLock.md
new file mode 100644
index 00000000..26129dc4
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLock.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem')
+
+## FileDistributedLock Class
+
+A distributed lock based on holding an exclusive handle to a lock file. The file will be deleted when the lock is released.
+
+```csharp
+public sealed class FileDistributedLock :
+Medallion.Threading.IDistributedLock
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 FileDistributedLock
+
+Implements [IDistributedLock](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.md 'Medallion.Threading.IDistributedLock')
+
+| Constructors | |
+| :--- | :--- |
+| [FileDistributedLock(DirectoryInfo, string)](FileDistributedLock..ctor.vNzzxMsPVMiUjD+hEvX7EQ.md 'Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.DirectoryInfo, string)') | Constructs a lock which will place a lock file in [lockFileDirectory](FileDistributedLock..ctor.vNzzxMsPVMiUjD+hEvX7EQ.md#Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.DirectoryInfo,string).lockFileDirectory 'Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.DirectoryInfo, string).lockFileDirectory'). The file's name will be based on [name](FileDistributedLock..ctor.vNzzxMsPVMiUjD+hEvX7EQ.md#Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.DirectoryInfo,string).name 'Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.DirectoryInfo, string).name'), but with proper escaping/hashing to ensure that a valid file name is produced. Upon acquiring the lock, the file's directory will be created automatically if it does not already exist. The file will similarly be created if it does not already exist, and will be deleted when the lock is released. |
+| [FileDistributedLock(FileInfo)](FileDistributedLock..ctor./N7mTMuqXSs9QBL49fhQcQ.md 'Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.FileInfo)') | Constructs a lock which uses the provided [lockFile](FileDistributedLock..ctor./N7mTMuqXSs9QBL49fhQcQ.md#Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.FileInfo).lockFile 'Medallion.Threading.FileSystem.FileDistributedLock.FileDistributedLock(System.IO.FileInfo).lockFile') as the exact file name. Upon acquiring the lock, the file's directory will be created automatically if it does not already exist. The file will similarly be created if it does not already exist, and will be deleted when the lock is released. |
+
+| Properties | |
+| :--- | :--- |
+| [Name](FileDistributedLock.Name.md 'Medallion.Threading.FileSystem.FileDistributedLock.Name') | Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name') |
+
+| Methods | |
+| :--- | :--- |
+| [Acquire(Nullable<TimeSpan>, CancellationToken)](FileDistributedLock.Acquire.Cxe4kn5Dotos0VNT8S7mFg.md 'Medallion.Threading.FileSystem.FileDistributedLock.Acquire(System.Nullable, System.Threading.CancellationToken)') | Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](FileDistributedLock.AcquireAsync.S5lCsEuKHmzK+f7lUXq+aw.md 'Medallion.Threading.FileSystem.FileDistributedLock.AcquireAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [TryAcquire(TimeSpan, CancellationToken)](FileDistributedLock.TryAcquire.zN8fZOiOkhzpcu5NxeJk8g.md 'Medallion.Threading.FileSystem.FileDistributedLock.TryAcquire(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire the lock synchronously. Usage: |
+| [TryAcquireAsync(TimeSpan, CancellationToken)](FileDistributedLock.TryAcquireAsync.VuLjCVM0f9HO9kvR8wPWxQ.md 'Medallion.Threading.FileSystem.FileDistributedLock.TryAcquireAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire the lock asynchronously. Usage: |
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLockHandle.Dispose().md b/docs/api/DistributedLock.FileSystem/FileDistributedLockHandle.Dispose().md
new file mode 100644
index 00000000..028fdd50
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLockHandle.Dispose().md
@@ -0,0 +1,12 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle')
+
+## FileDistributedLockHandle.Dispose() Method
+
+Releases the lock
+
+```csharp
+public void Dispose();
+```
+
+Implements [Dispose()](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable.Dispose 'System.IDisposable.Dispose')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLockHandle.DisposeAsync().md b/docs/api/DistributedLock.FileSystem/FileDistributedLockHandle.DisposeAsync().md
new file mode 100644
index 00000000..d5fbc129
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLockHandle.DisposeAsync().md
@@ -0,0 +1,15 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle')
+
+## FileDistributedLockHandle.DisposeAsync() Method
+
+Releases the lock
+
+```csharp
+public System.Threading.Tasks.ValueTask DisposeAsync();
+```
+
+Implements [DisposeAsync()](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable.DisposeAsync 'System.IAsyncDisposable.DisposeAsync')
+
+#### Returns
+[System.Threading.Tasks.ValueTask](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask 'System.Threading.Tasks.ValueTask')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedLockHandle.md b/docs/api/DistributedLock.FileSystem/FileDistributedLockHandle.md
new file mode 100644
index 00000000..07e80991
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedLockHandle.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem')
+
+## FileDistributedLockHandle Class
+
+Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+
+```csharp
+public sealed class FileDistributedLockHandle :
+Medallion.Threading.IDistributedSynchronizationHandle,
+System.IDisposable,
+System.IAsyncDisposable
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 FileDistributedLockHandle
+
+Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle'), [System.IDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable 'System.IDisposable'), [System.IAsyncDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable 'System.IAsyncDisposable')
+
+| Methods | |
+| :--- | :--- |
+| [Dispose()](FileDistributedLockHandle.Dispose().md 'Medallion.Threading.FileSystem.FileDistributedLockHandle.Dispose()') | Releases the lock |
+| [DisposeAsync()](FileDistributedLockHandle.DisposeAsync().md 'Medallion.Threading.FileSystem.FileDistributedLockHandle.DisposeAsync()') | Releases the lock |
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedSynchronizationProvider..ctor.TETT6F6M/CskpBpX2hNqtA.md b/docs/api/DistributedLock.FileSystem/FileDistributedSynchronizationProvider..ctor.TETT6F6M/CskpBpX2hNqtA.md
new file mode 100644
index 00000000..a0b75918
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedSynchronizationProvider..ctor.TETT6F6M/CskpBpX2hNqtA.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedSynchronizationProvider](FileDistributedSynchronizationProvider.md 'Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider')
+
+## FileDistributedSynchronizationProvider(DirectoryInfo) Constructor
+
+Constructs a provider that scopes lock files within the provided [lockFileDirectory](FileDistributedSynchronizationProvider..ctor.TETT6F6M/CskpBpX2hNqtA.md#Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider.FileDistributedSynchronizationProvider(System.IO.DirectoryInfo).lockFileDirectory 'Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider.FileDistributedSynchronizationProvider(System.IO.DirectoryInfo).lockFileDirectory').
+
+```csharp
+public FileDistributedSynchronizationProvider(System.IO.DirectoryInfo lockFileDirectory);
+```
+#### Parameters
+
+
+
+`lockFileDirectory` [System.IO.DirectoryInfo](https://docs.microsoft.com/en-us/dotnet/api/System.IO.DirectoryInfo 'System.IO.DirectoryInfo')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedSynchronizationProvider.CreateLock.bu/BmarBn5NPtnEydKr3pQ.md b/docs/api/DistributedLock.FileSystem/FileDistributedSynchronizationProvider.CreateLock.bu/BmarBn5NPtnEydKr3pQ.md
new file mode 100644
index 00000000..ef2e84e8
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedSynchronizationProvider.CreateLock.bu/BmarBn5NPtnEydKr3pQ.md
@@ -0,0 +1,20 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem').[FileDistributedSynchronizationProvider](FileDistributedSynchronizationProvider.md 'Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider')
+
+## FileDistributedSynchronizationProvider.CreateLock(string) Method
+
+Constructs a [FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock') with the given [name](FileDistributedSynchronizationProvider.CreateLock.bu/BmarBn5NPtnEydKr3pQ.md#Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider.CreateLock(string).name 'Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider.CreateLock(string).name').
+
+```csharp
+public Medallion.Threading.FileSystem.FileDistributedLock CreateLock(string name);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+Implements [CreateLock(string)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.CreateLock.lcl3dolUp9eZyeUENeHU9w.md 'Medallion.Threading.IDistributedLockProvider.CreateLock(System.String)')
+
+#### Returns
+[FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.FileSystem/FileDistributedSynchronizationProvider.md b/docs/api/DistributedLock.FileSystem/FileDistributedSynchronizationProvider.md
new file mode 100644
index 00000000..fbe7a8bb
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/FileDistributedSynchronizationProvider.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+### [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem')
+
+## FileDistributedSynchronizationProvider Class
+
+Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') for [FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock')
+
+```csharp
+public sealed class FileDistributedSynchronizationProvider :
+Medallion.Threading.IDistributedLockProvider
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 FileDistributedSynchronizationProvider
+
+Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider')
+
+| Constructors | |
+| :--- | :--- |
+| [FileDistributedSynchronizationProvider(DirectoryInfo)](FileDistributedSynchronizationProvider..ctor.TETT6F6M/CskpBpX2hNqtA.md 'Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider.FileDistributedSynchronizationProvider(System.IO.DirectoryInfo)') | Constructs a provider that scopes lock files within the provided [lockFileDirectory](FileDistributedSynchronizationProvider..ctor.TETT6F6M/CskpBpX2hNqtA.md#Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider.FileDistributedSynchronizationProvider(System.IO.DirectoryInfo).lockFileDirectory 'Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider.FileDistributedSynchronizationProvider(System.IO.DirectoryInfo).lockFileDirectory'). |
+
+| Methods | |
+| :--- | :--- |
+| [CreateLock(string)](FileDistributedSynchronizationProvider.CreateLock.bu/BmarBn5NPtnEydKr3pQ.md 'Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider.CreateLock(string)') | Constructs a [FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock') with the given [name](FileDistributedSynchronizationProvider.CreateLock.bu/BmarBn5NPtnEydKr3pQ.md#Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider.CreateLock(string).name 'Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider.CreateLock(string).name'). |
diff --git a/docs/api/DistributedLock.FileSystem/Medallion.Threading.FileSystem.md b/docs/api/DistributedLock.FileSystem/Medallion.Threading.FileSystem.md
new file mode 100644
index 00000000..8e31121b
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/Medallion.Threading.FileSystem.md
@@ -0,0 +1,9 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+
+## Medallion.Threading.FileSystem Namespace
+
+| Classes | |
+| :--- | :--- |
+| [FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock') | A distributed lock based on holding an exclusive handle to a lock file. The file will be deleted when the lock is released. |
+| [FileDistributedLockHandle](FileDistributedLockHandle.md 'Medallion.Threading.FileSystem.FileDistributedLockHandle') | Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') |
+| [FileDistributedSynchronizationProvider](FileDistributedSynchronizationProvider.md 'Medallion.Threading.FileSystem.FileDistributedSynchronizationProvider') | Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') for [FileDistributedLock](FileDistributedLock.md 'Medallion.Threading.FileSystem.FileDistributedLock') |
diff --git a/docs/api/DistributedLock.FileSystem/README.md b/docs/api/DistributedLock.FileSystem/README.md
new file mode 100644
index 00000000..af21cc86
--- /dev/null
+++ b/docs/api/DistributedLock.FileSystem/README.md
@@ -0,0 +1,7 @@
+#### [DistributedLock.FileSystem](README.md 'README')
+
+## DistributedLock.FileSystem Assembly
+
+| Namespaces | |
+| :--- | :--- |
+| [Medallion.Threading.FileSystem](Medallion.Threading.FileSystem.md 'Medallion.Threading.FileSystem') | |
diff --git a/docs/api/DistributedLock.MySql/Medallion.Threading.MySql.md b/docs/api/DistributedLock.MySql/Medallion.Threading.MySql.md
new file mode 100644
index 00000000..a77d9287
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/Medallion.Threading.MySql.md
@@ -0,0 +1,10 @@
+#### [DistributedLock.MySql](README.md 'README')
+
+## Medallion.Threading.MySql Namespace
+
+| Classes | |
+| :--- | :--- |
+| [MySqlConnectionOptionsBuilder](MySqlConnectionOptionsBuilder.md 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder') | Specifies options for connecting to and locking against a MySQL database |
+| [MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock') | Implements a distributed lock for MySQL or MariaDB based on the GET_LOCK family of functions |
+| [MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle') | Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') |
+| [MySqlDistributedSynchronizationProvider](MySqlDistributedSynchronizationProvider.md 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider') | Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') for [MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock') |
diff --git a/docs/api/DistributedLock.MySql/MySqlConnectionOptionsBuilder.KeepaliveCadence.UQXLJo99rQgbid2s4ZOgRQ.md b/docs/api/DistributedLock.MySql/MySqlConnectionOptionsBuilder.KeepaliveCadence.UQXLJo99rQgbid2s4ZOgRQ.md
new file mode 100644
index 00000000..bf8369b1
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlConnectionOptionsBuilder.KeepaliveCadence.UQXLJo99rQgbid2s4ZOgRQ.md
@@ -0,0 +1,25 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlConnectionOptionsBuilder](MySqlConnectionOptionsBuilder.md 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder')
+
+## MySqlConnectionOptionsBuilder.KeepaliveCadence(TimeSpan) Method
+
+MySQL's wait_timeout system variable determines how long the server will allow a connection to be idle before killing it.
+For more information, see https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_wait_timeout.
+
+To prevent this, this option sets the cadence at which we run a no-op "keepalive" query on a connection that is holding a lock.
+
+Because MySQL's default for this setting is 8 hours, the default [keepaliveCadence](MySqlConnectionOptionsBuilder.KeepaliveCadence.UQXLJo99rQgbid2s4ZOgRQ.md#Medallion.Threading.MySql.MySqlConnectionOptionsBuilder.KeepaliveCadence(System.TimeSpan).keepaliveCadence 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder.KeepaliveCadence(System.TimeSpan).keepaliveCadence') is 3.5 hours.
+
+Setting a value of [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan') disables keepalive.
+
+```csharp
+public Medallion.Threading.MySql.MySqlConnectionOptionsBuilder KeepaliveCadence(System.TimeSpan keepaliveCadence);
+```
+#### Parameters
+
+
+
+`keepaliveCadence` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+#### Returns
+[MySqlConnectionOptionsBuilder](MySqlConnectionOptionsBuilder.md 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlConnectionOptionsBuilder.UseMultiplexing.fKIzw1BfXbV8NLqGfoikqw.md b/docs/api/DistributedLock.MySql/MySqlConnectionOptionsBuilder.UseMultiplexing.fKIzw1BfXbV8NLqGfoikqw.md
new file mode 100644
index 00000000..0ad5d4f2
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlConnectionOptionsBuilder.UseMultiplexing.fKIzw1BfXbV8NLqGfoikqw.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlConnectionOptionsBuilder](MySqlConnectionOptionsBuilder.md 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder')
+
+## MySqlConnectionOptionsBuilder.UseMultiplexing(bool) Method
+
+This mode takes advantage of the fact that while "holding" a lock (or other synchronization primitive)
+a connection is essentially idle. Thus, rather than creating a new connection for each held lock it is
+often possible to multiplex a shared connection so that that connection can hold multiple locks at the same time.
+
+Multiplexing is on by default.
+
+This is implemented in such a way that releasing a lock held on such a connection will never be blocked by an
+Acquire() call that is waiting to acquire a lock on that same connection. For this reason, the multiplexing
+strategy is "optimistic": if the lock can't be acquired instantaneously on the shared connection, a new (shareable)
+connection will be allocated.
+
+This option can improve performance and avoid connection pool starvation in high-load scenarios. It is also
+particularly applicable to cases where [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)')
+semantics are used with a zero-length timeout.
+
+```csharp
+public Medallion.Threading.MySql.MySqlConnectionOptionsBuilder UseMultiplexing(bool useMultiplexing=true);
+```
+#### Parameters
+
+
+
+`useMultiplexing` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+#### Returns
+[MySqlConnectionOptionsBuilder](MySqlConnectionOptionsBuilder.md 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlConnectionOptionsBuilder.md b/docs/api/DistributedLock.MySql/MySqlConnectionOptionsBuilder.md
new file mode 100644
index 00000000..2e6f07d7
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlConnectionOptionsBuilder.md
@@ -0,0 +1,17 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql')
+
+## MySqlConnectionOptionsBuilder Class
+
+Specifies options for connecting to and locking against a MySQL database
+
+```csharp
+public sealed class MySqlConnectionOptionsBuilder
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 MySqlConnectionOptionsBuilder
+
+| Methods | |
+| :--- | :--- |
+| [KeepaliveCadence(TimeSpan)](MySqlConnectionOptionsBuilder.KeepaliveCadence.UQXLJo99rQgbid2s4ZOgRQ.md 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder.KeepaliveCadence(System.TimeSpan)') | MySQL's wait_timeout system variable determines how long the server will allow a connection to be idle before killing it. For more information, see https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_wait_timeout. To prevent this, this option sets the cadence at which we run a no-op "keepalive" query on a connection that is holding a lock. Because MySQL's default for this setting is 8 hours, the default [keepaliveCadence](MySqlConnectionOptionsBuilder.KeepaliveCadence.UQXLJo99rQgbid2s4ZOgRQ.md#Medallion.Threading.MySql.MySqlConnectionOptionsBuilder.KeepaliveCadence(System.TimeSpan).keepaliveCadence 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder.KeepaliveCadence(System.TimeSpan).keepaliveCadence') is 3.5 hours. Setting a value of [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan') disables keepalive. |
+| [UseMultiplexing(bool)](MySqlConnectionOptionsBuilder.UseMultiplexing.fKIzw1BfXbV8NLqGfoikqw.md 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder.UseMultiplexing(bool)') | This mode takes advantage of the fact that while "holding" a lock (or other synchronization primitive) a connection is essentially idle. Thus, rather than creating a new connection for each held lock it is often possible to multiplex a shared connection so that that connection can hold multiple locks at the same time. Multiplexing is on by default. This is implemented in such a way that releasing a lock held on such a connection will never be blocked by an Acquire() call that is waiting to acquire a lock on that same connection. For this reason, the multiplexing strategy is "optimistic": if the lock can't be acquired instantaneously on the shared connection, a new (shareable) connection will be allocated. This option can improve performance and avoid connection pool starvation in high-load scenarios. It is also particularly applicable to cases where [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)') semantics are used with a zero-length timeout. |
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md b/docs/api/DistributedLock.MySql/MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md
new file mode 100644
index 00000000..96ee2f36
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md
@@ -0,0 +1,28 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock')
+
+## MySqlDistributedLock(string, IDbTransaction, bool) Constructor
+
+Constructs a lock with the given [name](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbTransaction,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool).name') that connects using the connection from the provided [transaction](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbTransaction,bool).transaction 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool).transaction').
+
+NOTE that the lock will not be scoped to the [transaction](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbTransaction,bool).transaction 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool).transaction') and must still be explicitly released before the transaction ends.
+However, this constructor allows the lock to PARTICIPATE in an ongoing transaction on a connection.
+
+Unless [exactName](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbTransaction,bool).exactName 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool).exactName') is specified, [name](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbTransaction,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool).name') will be escaped/hashed to ensure name validity.
+
+```csharp
+public MySqlDistributedLock(string name, System.Data.IDbTransaction transaction, bool exactName=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`transaction` [System.Data.IDbTransaction](https://docs.microsoft.com/en-us/dotnet/api/System.Data.IDbTransaction 'System.Data.IDbTransaction')
+
+
+
+`exactName` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md b/docs/api/DistributedLock.MySql/MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md
new file mode 100644
index 00000000..ebeb82a0
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md
@@ -0,0 +1,25 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock')
+
+## MySqlDistributedLock(string, IDbConnection, bool) Constructor
+
+Constructs a lock with the given [name](MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbConnection, bool).name') that connects using the provided [connection](MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbConnection,bool).connection 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbConnection, bool).connection').
+
+Unless [exactName](MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbConnection,bool).exactName 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbConnection, bool).exactName') is specified, [name](MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbConnection, bool).name') will be escaped/hashed to ensure name validity.
+
+```csharp
+public MySqlDistributedLock(string name, System.Data.IDbConnection connection, bool exactName=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`connection` [System.Data.IDbConnection](https://docs.microsoft.com/en-us/dotnet/api/System.Data.IDbConnection 'System.Data.IDbConnection')
+
+
+
+`exactName` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md b/docs/api/DistributedLock.MySql/MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md
new file mode 100644
index 00000000..bdfad860
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md
@@ -0,0 +1,30 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock')
+
+## MySqlDistributedLock(string, string, Action, bool) Constructor
+
+Constructs a lock with the given [name](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool).name') that connects using the provided [connectionString](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_,bool).connectionString 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool).connectionString') and
+[options](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_,bool).options 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool).options').
+
+Unless [exactName](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_,bool).exactName 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool).exactName') is specified, [name](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool).name') will be escaped/hashed to ensure name validity.
+
+```csharp
+public MySqlDistributedLock(string name, string connectionString, System.Action? options=null, bool exactName=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`connectionString` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`options` [System.Action<](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')[MySqlConnectionOptionsBuilder](MySqlConnectionOptionsBuilder.md 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')
+
+
+
+`exactName` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLock.Acquire.r/fV/58/g2xfKSkMNPcJIQ.md b/docs/api/DistributedLock.MySql/MySqlDistributedLock.Acquire.r/fV/58/g2xfKSkMNPcJIQ.md
new file mode 100644
index 00000000..2087a17e
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLock.Acquire.r/fV/58/g2xfKSkMNPcJIQ.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock')
+
+## MySqlDistributedLock.Acquire(Nullable, CancellationToken) Method
+
+Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+using (myLock.Acquire(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public Medallion.Threading.MySql.MySqlDistributedLockHandle Acquire(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [Acquire(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md 'Medallion.Threading.IDistributedLock.Acquire(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle')
+A [MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLock.AcquireAsync.4BoOdZqpZP277VPAU321Nw.md b/docs/api/DistributedLock.MySql/MySqlDistributedLock.AcquireAsync.4BoOdZqpZP277VPAU321Nw.md
new file mode 100644
index 00000000..5aacdcf1
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLock.AcquireAsync.4BoOdZqpZP277VPAU321Nw.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock')
+
+## MySqlDistributedLock.AcquireAsync(Nullable, CancellationToken) Method
+
+Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+await using (await myLock.AcquireAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask AcquireAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md 'Medallion.Threading.IDistributedLock.AcquireAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+A [MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLock.Name.md b/docs/api/DistributedLock.MySql/MySqlDistributedLock.Name.md
new file mode 100644
index 00000000..c385e7d4
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLock.Name.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock')
+
+## MySqlDistributedLock.Name Property
+
+Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name')
+
+```csharp
+public string Name { get; }
+```
+
+Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name')
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLock.TryAcquire.7Uu3aSVcXR87JPC85D/j6w.md b/docs/api/DistributedLock.MySql/MySqlDistributedLock.TryAcquire.7Uu3aSVcXR87JPC85D/j6w.md
new file mode 100644
index 00000000..d534e3ce
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLock.TryAcquire.7Uu3aSVcXR87JPC85D/j6w.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock')
+
+## MySqlDistributedLock.TryAcquire(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock synchronously. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquire(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public Medallion.Threading.MySql.MySqlDistributedLockHandle? TryAcquire(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle')
+A [MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLock.TryAcquireAsync.PuScySfWO2UMl6rfaBoiww.md b/docs/api/DistributedLock.MySql/MySqlDistributedLock.TryAcquireAsync.PuScySfWO2UMl6rfaBoiww.md
new file mode 100644
index 00000000..3d7262fc
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLock.TryAcquireAsync.PuScySfWO2UMl6rfaBoiww.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock')
+
+## MySqlDistributedLock.TryAcquireAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock asynchronously. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask TryAcquireAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md 'Medallion.Threading.IDistributedLock.TryAcquireAsync(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+A [MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLock.md b/docs/api/DistributedLock.MySql/MySqlDistributedLock.md
new file mode 100644
index 00000000..8273b3dc
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLock.md
@@ -0,0 +1,32 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql')
+
+## MySqlDistributedLock Class
+
+Implements a distributed lock for MySQL or MariaDB based on the GET_LOCK family of functions
+
+```csharp
+public sealed class MySqlDistributedLock :
+Medallion.Threading.IDistributedLock
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 MySqlDistributedLock
+
+Implements [IDistributedLock](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.md 'Medallion.Threading.IDistributedLock')
+
+| Constructors | |
+| :--- | :--- |
+| [MySqlDistributedLock(string, string, Action<MySqlConnectionOptionsBuilder>, bool)](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool)') | Constructs a lock with the given [name](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool).name') that connects using the provided [connectionString](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_,bool).connectionString 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool).connectionString') and [options](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_,bool).options 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool).options'). Unless [exactName](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_,bool).exactName 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool).exactName') is specified, [name](MySqlDistributedLock..ctor.PsVoAEVfWkGp+4s0eOgjkA.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, string, System.Action, bool).name') will be escaped/hashed to ensure name validity. |
+| [MySqlDistributedLock(string, IDbConnection, bool)](MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbConnection, bool)') | Constructs a lock with the given [name](MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbConnection, bool).name') that connects using the provided [connection](MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbConnection,bool).connection 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbConnection, bool).connection'). Unless [exactName](MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbConnection,bool).exactName 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbConnection, bool).exactName') is specified, [name](MySqlDistributedLock..ctor.Gw0JTgvDod2OkXGtyloMgg.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbConnection, bool).name') will be escaped/hashed to ensure name validity. |
+| [MySqlDistributedLock(string, IDbTransaction, bool)](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool)') | Constructs a lock with the given [name](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbTransaction,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool).name') that connects using the connection from the provided [transaction](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbTransaction,bool).transaction 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool).transaction'). NOTE that the lock will not be scoped to the [transaction](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbTransaction,bool).transaction 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool).transaction') and must still be explicitly released before the transaction ends. However, this constructor allows the lock to PARTICIPATE in an ongoing transaction on a connection. Unless [exactName](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbTransaction,bool).exactName 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool).exactName') is specified, [name](MySqlDistributedLock..ctor.7PfsrTn0xgkLTsBbB0BbVw.md#Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string,System.Data.IDbTransaction,bool).name 'Medallion.Threading.MySql.MySqlDistributedLock.MySqlDistributedLock(string, System.Data.IDbTransaction, bool).name') will be escaped/hashed to ensure name validity. |
+
+| Properties | |
+| :--- | :--- |
+| [Name](MySqlDistributedLock.Name.md 'Medallion.Threading.MySql.MySqlDistributedLock.Name') | Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name') |
+
+| Methods | |
+| :--- | :--- |
+| [Acquire(Nullable<TimeSpan>, CancellationToken)](MySqlDistributedLock.Acquire.r/fV/58/g2xfKSkMNPcJIQ.md 'Medallion.Threading.MySql.MySqlDistributedLock.Acquire(System.Nullable, System.Threading.CancellationToken)') | Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](MySqlDistributedLock.AcquireAsync.4BoOdZqpZP277VPAU321Nw.md 'Medallion.Threading.MySql.MySqlDistributedLock.AcquireAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [TryAcquire(TimeSpan, CancellationToken)](MySqlDistributedLock.TryAcquire.7Uu3aSVcXR87JPC85D/j6w.md 'Medallion.Threading.MySql.MySqlDistributedLock.TryAcquire(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire the lock synchronously. Usage: |
+| [TryAcquireAsync(TimeSpan, CancellationToken)](MySqlDistributedLock.TryAcquireAsync.PuScySfWO2UMl6rfaBoiww.md 'Medallion.Threading.MySql.MySqlDistributedLock.TryAcquireAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire the lock asynchronously. Usage: |
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.Dispose().md b/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.Dispose().md
new file mode 100644
index 00000000..519e28a1
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.Dispose().md
@@ -0,0 +1,12 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle')
+
+## MySqlDistributedLockHandle.Dispose() Method
+
+Releases the lock
+
+```csharp
+public void Dispose();
+```
+
+Implements [Dispose()](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable.Dispose 'System.IDisposable.Dispose')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.DisposeAsync().md b/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.DisposeAsync().md
new file mode 100644
index 00000000..fd822106
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.DisposeAsync().md
@@ -0,0 +1,15 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle')
+
+## MySqlDistributedLockHandle.DisposeAsync() Method
+
+Releases the lock asynchronously
+
+```csharp
+public System.Threading.Tasks.ValueTask DisposeAsync();
+```
+
+Implements [DisposeAsync()](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable.DisposeAsync 'System.IAsyncDisposable.DisposeAsync')
+
+#### Returns
+[System.Threading.Tasks.ValueTask](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask 'System.Threading.Tasks.ValueTask')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.HandleLostToken.md b/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.HandleLostToken.md
new file mode 100644
index 00000000..4ae9f02f
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.HandleLostToken.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedLockHandle](MySqlDistributedLockHandle.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle')
+
+## MySqlDistributedLockHandle.HandleLostToken Property
+
+Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken')
+
+```csharp
+public System.Threading.CancellationToken HandleLostToken { get; }
+```
+
+Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken')
+
+#### Property Value
+[System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.md b/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.md
new file mode 100644
index 00000000..84c60c41
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedLockHandle.md
@@ -0,0 +1,26 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql')
+
+## MySqlDistributedLockHandle Class
+
+Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+
+```csharp
+public sealed class MySqlDistributedLockHandle :
+Medallion.Threading.IDistributedSynchronizationHandle,
+System.IDisposable,
+System.IAsyncDisposable
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 MySqlDistributedLockHandle
+
+Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle'), [System.IDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable 'System.IDisposable'), [System.IAsyncDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable 'System.IAsyncDisposable')
+
+| Properties | |
+| :--- | :--- |
+| [HandleLostToken](MySqlDistributedLockHandle.HandleLostToken.md 'Medallion.Threading.MySql.MySqlDistributedLockHandle.HandleLostToken') | Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken') |
+
+| Methods | |
+| :--- | :--- |
+| [Dispose()](MySqlDistributedLockHandle.Dispose().md 'Medallion.Threading.MySql.MySqlDistributedLockHandle.Dispose()') | Releases the lock |
+| [DisposeAsync()](MySqlDistributedLockHandle.DisposeAsync().md 'Medallion.Threading.MySql.MySqlDistributedLockHandle.DisposeAsync()') | Releases the lock asynchronously |
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider..ctor.p7z4Ra8yKm8ddj1YbCV32w.md b/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider..ctor.p7z4Ra8yKm8ddj1YbCV32w.md
new file mode 100644
index 00000000..8cfc4764
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider..ctor.p7z4Ra8yKm8ddj1YbCV32w.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedSynchronizationProvider](MySqlDistributedSynchronizationProvider.md 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider')
+
+## MySqlDistributedSynchronizationProvider(IDbTransaction) Constructor
+
+Constructs a provider that connects with [transaction](MySqlDistributedSynchronizationProvider..ctor.p7z4Ra8yKm8ddj1YbCV32w.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(System.Data.IDbTransaction).transaction 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(System.Data.IDbTransaction).transaction').
+
+```csharp
+public MySqlDistributedSynchronizationProvider(System.Data.IDbTransaction transaction);
+```
+#### Parameters
+
+
+
+`transaction` [System.Data.IDbTransaction](https://docs.microsoft.com/en-us/dotnet/api/System.Data.IDbTransaction 'System.Data.IDbTransaction')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider..ctor.pke77kyAr68Nsic0RCNm1g.md b/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider..ctor.pke77kyAr68Nsic0RCNm1g.md
new file mode 100644
index 00000000..42e95bd4
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider..ctor.pke77kyAr68Nsic0RCNm1g.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedSynchronizationProvider](MySqlDistributedSynchronizationProvider.md 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider')
+
+## MySqlDistributedSynchronizationProvider(IDbConnection) Constructor
+
+Constructs a provider that connects with [connection](MySqlDistributedSynchronizationProvider..ctor.pke77kyAr68Nsic0RCNm1g.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(System.Data.IDbConnection).connection 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(System.Data.IDbConnection).connection').
+
+```csharp
+public MySqlDistributedSynchronizationProvider(System.Data.IDbConnection connection);
+```
+#### Parameters
+
+
+
+`connection` [System.Data.IDbConnection](https://docs.microsoft.com/en-us/dotnet/api/System.Data.IDbConnection 'System.Data.IDbConnection')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider..ctor/nOe7Is6T7o1EV/QK7Yew.md b/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider..ctor/nOe7Is6T7o1EV/QK7Yew.md
new file mode 100644
index 00000000..99c21b1d
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider..ctor/nOe7Is6T7o1EV/QK7Yew.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedSynchronizationProvider](MySqlDistributedSynchronizationProvider.md 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider')
+
+## MySqlDistributedSynchronizationProvider(string, Action) Constructor
+
+Constructs a provider that connects with [connectionString](MySqlDistributedSynchronizationProvider..ctor.//nOe7Is6T7o1EV/QK7Yew.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_).connectionString 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(string, System.Action).connectionString') and [options](MySqlDistributedSynchronizationProvider..ctor.//nOe7Is6T7o1EV/QK7Yew.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_).options 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(string, System.Action).options').
+
+```csharp
+public MySqlDistributedSynchronizationProvider(string connectionString, System.Action? options=null);
+```
+#### Parameters
+
+
+
+`connectionString` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`options` [System.Action<](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')[MySqlConnectionOptionsBuilder](MySqlConnectionOptionsBuilder.md 'Medallion.Threading.MySql.MySqlConnectionOptionsBuilder')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider.CreateLock.BfFkX376FOT5FK96U7Fr1g.md b/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider.CreateLock.BfFkX376FOT5FK96U7Fr1g.md
new file mode 100644
index 00000000..195ffac4
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider.CreateLock.BfFkX376FOT5FK96U7Fr1g.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql').[MySqlDistributedSynchronizationProvider](MySqlDistributedSynchronizationProvider.md 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider')
+
+## MySqlDistributedSynchronizationProvider.CreateLock(string, bool) Method
+
+Creates a [MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock') with the provided [name](MySqlDistributedSynchronizationProvider.CreateLock.BfFkX376FOT5FK96U7Fr1g.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.CreateLock(string,bool).name 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.CreateLock(string, bool).name'). Unless [exactName](MySqlDistributedSynchronizationProvider.CreateLock.BfFkX376FOT5FK96U7Fr1g.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.CreateLock(string,bool).exactName 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.CreateLock(string, bool).exactName')
+is specified, invalid names will be escaped/hashed.
+
+```csharp
+public Medallion.Threading.MySql.MySqlDistributedLock CreateLock(string name, bool exactName=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`exactName` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+#### Returns
+[MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider.md b/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider.md
new file mode 100644
index 00000000..25839810
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/MySqlDistributedSynchronizationProvider.md
@@ -0,0 +1,25 @@
+#### [DistributedLock.MySql](README.md 'README')
+### [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql')
+
+## MySqlDistributedSynchronizationProvider Class
+
+Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') for [MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock')
+
+```csharp
+public sealed class MySqlDistributedSynchronizationProvider :
+Medallion.Threading.IDistributedLockProvider
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 MySqlDistributedSynchronizationProvider
+
+Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider')
+
+| Constructors | |
+| :--- | :--- |
+| [MySqlDistributedSynchronizationProvider(string, Action<MySqlConnectionOptionsBuilder>)](MySqlDistributedSynchronizationProvider..ctor.//nOe7Is6T7o1EV/QK7Yew.md 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(string, System.Action)') | Constructs a provider that connects with [connectionString](MySqlDistributedSynchronizationProvider..ctor.//nOe7Is6T7o1EV/QK7Yew.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_).connectionString 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(string, System.Action).connectionString') and [options](MySqlDistributedSynchronizationProvider..ctor.//nOe7Is6T7o1EV/QK7Yew.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(string,System.Action_Medallion.Threading.MySql.MySqlConnectionOptionsBuilder_).options 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(string, System.Action).options'). |
+| [MySqlDistributedSynchronizationProvider(IDbConnection)](MySqlDistributedSynchronizationProvider..ctor.pke77kyAr68Nsic0RCNm1g.md 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(System.Data.IDbConnection)') | Constructs a provider that connects with [connection](MySqlDistributedSynchronizationProvider..ctor.pke77kyAr68Nsic0RCNm1g.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(System.Data.IDbConnection).connection 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(System.Data.IDbConnection).connection'). |
+| [MySqlDistributedSynchronizationProvider(IDbTransaction)](MySqlDistributedSynchronizationProvider..ctor.p7z4Ra8yKm8ddj1YbCV32w.md 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(System.Data.IDbTransaction)') | Constructs a provider that connects with [transaction](MySqlDistributedSynchronizationProvider..ctor.p7z4Ra8yKm8ddj1YbCV32w.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(System.Data.IDbTransaction).transaction 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.MySqlDistributedSynchronizationProvider(System.Data.IDbTransaction).transaction'). |
+
+| Methods | |
+| :--- | :--- |
+| [CreateLock(string, bool)](MySqlDistributedSynchronizationProvider.CreateLock.BfFkX376FOT5FK96U7Fr1g.md 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.CreateLock(string, bool)') | Creates a [MySqlDistributedLock](MySqlDistributedLock.md 'Medallion.Threading.MySql.MySqlDistributedLock') with the provided [name](MySqlDistributedSynchronizationProvider.CreateLock.BfFkX376FOT5FK96U7Fr1g.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.CreateLock(string,bool).name 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.CreateLock(string, bool).name'). Unless [exactName](MySqlDistributedSynchronizationProvider.CreateLock.BfFkX376FOT5FK96U7Fr1g.md#Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.CreateLock(string,bool).exactName 'Medallion.Threading.MySql.MySqlDistributedSynchronizationProvider.CreateLock(string, bool).exactName') is specified, invalid names will be escaped/hashed. |
diff --git a/docs/api/DistributedLock.MySql/README.md b/docs/api/DistributedLock.MySql/README.md
new file mode 100644
index 00000000..e89e09f3
--- /dev/null
+++ b/docs/api/DistributedLock.MySql/README.md
@@ -0,0 +1,7 @@
+#### [DistributedLock.MySql](README.md 'README')
+
+## DistributedLock.MySql Assembly
+
+| Namespaces | |
+| :--- | :--- |
+| [Medallion.Threading.MySql](Medallion.Threading.MySql.md 'Medallion.Threading.MySql') | |
diff --git a/docs/api/DistributedLock.Oracle/Medallion.Threading.Oracle.md b/docs/api/DistributedLock.Oracle/Medallion.Threading.Oracle.md
new file mode 100644
index 00000000..cb41c30b
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/Medallion.Threading.Oracle.md
@@ -0,0 +1,13 @@
+#### [DistributedLock.Oracle](README.md 'README')
+
+## Medallion.Threading.Oracle Namespace
+
+| Classes | |
+| :--- | :--- |
+| [OracleConnectionOptionsBuilder](OracleConnectionOptionsBuilder.md 'Medallion.Threading.Oracle.OracleConnectionOptionsBuilder') | Specifies options for connecting to and locking against an Oracle database |
+| [OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock') | Implements a distributed lock for Oracle databse based on the DBMS_LOCK package |
+| [OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle') | Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') |
+| [OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock') | Implements an upgradeable distributed reader-writer lock for the Oracle database using the DBMS_LOCK package. |
+| [OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle') | Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') |
+| [OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle') | Implements [IDistributedLockUpgradeableHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle') |
+| [OracleDistributedSynchronizationProvider](OracleDistributedSynchronizationProvider.md 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider') | Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') for [OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock') and [IDistributedUpgradeableReaderWriterLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider') for [OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock') |
diff --git a/docs/api/DistributedLock.Oracle/OracleConnectionOptionsBuilder.KeepaliveCadence.cpYoNdk/QhqJGH/58Hukqw.md b/docs/api/DistributedLock.Oracle/OracleConnectionOptionsBuilder.KeepaliveCadence.cpYoNdk/QhqJGH/58Hukqw.md
new file mode 100644
index 00000000..2d5613c4
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleConnectionOptionsBuilder.KeepaliveCadence.cpYoNdk/QhqJGH/58Hukqw.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleConnectionOptionsBuilder](OracleConnectionOptionsBuilder.md 'Medallion.Threading.Oracle.OracleConnectionOptionsBuilder')
+
+## OracleConnectionOptionsBuilder.KeepaliveCadence(TimeSpan) Method
+
+Oracle does not kill idle connections by default, so by default keepalive is disabled (set to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')).
+
+However, if you are using the IDLE_TIME setting in Oracle or if your network is dropping connections that are idle holding locks for
+a long time, you can set a value for keepalive to prevent this from happening.
+
+See https://stackoverflow.com/questions/1966247/idle-timeout-parameter-in-oracle.
+
+```csharp
+public Medallion.Threading.Oracle.OracleConnectionOptionsBuilder KeepaliveCadence(System.TimeSpan keepaliveCadence);
+```
+#### Parameters
+
+
+
+`keepaliveCadence` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+#### Returns
+[OracleConnectionOptionsBuilder](OracleConnectionOptionsBuilder.md 'Medallion.Threading.Oracle.OracleConnectionOptionsBuilder')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleConnectionOptionsBuilder.UseMultiplexing.A+iIKatFl3VDvz/7Q6X3Jg.md b/docs/api/DistributedLock.Oracle/OracleConnectionOptionsBuilder.UseMultiplexing.A+iIKatFl3VDvz/7Q6X3Jg.md
new file mode 100644
index 00000000..0e32628f
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleConnectionOptionsBuilder.UseMultiplexing.A+iIKatFl3VDvz/7Q6X3Jg.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleConnectionOptionsBuilder](OracleConnectionOptionsBuilder.md 'Medallion.Threading.Oracle.OracleConnectionOptionsBuilder')
+
+## OracleConnectionOptionsBuilder.UseMultiplexing(bool) Method
+
+This mode takes advantage of the fact that while "holding" a lock (or other synchronization primitive)
+a connection is essentially idle. Thus, rather than creating a new connection for each held lock it is
+often possible to multiplex a shared connection so that that connection can hold multiple locks at the same time.
+
+Multiplexing is on by default.
+
+This is implemented in such a way that releasing a lock held on such a connection will never be blocked by an
+Acquire() call that is waiting to acquire a lock on that same connection. For this reason, the multiplexing
+strategy is "optimistic": if the lock can't be acquired instantaneously on the shared connection, a new (shareable)
+connection will be allocated.
+
+This option can improve performance and avoid connection pool starvation in high-load scenarios. It is also
+particularly applicable to cases where [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)')
+semantics are used with a zero-length timeout.
+
+```csharp
+public Medallion.Threading.Oracle.OracleConnectionOptionsBuilder UseMultiplexing(bool useMultiplexing=true);
+```
+#### Parameters
+
+
+
+`useMultiplexing` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+#### Returns
+[OracleConnectionOptionsBuilder](OracleConnectionOptionsBuilder.md 'Medallion.Threading.Oracle.OracleConnectionOptionsBuilder')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleConnectionOptionsBuilder.md b/docs/api/DistributedLock.Oracle/OracleConnectionOptionsBuilder.md
new file mode 100644
index 00000000..7e8166a1
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleConnectionOptionsBuilder.md
@@ -0,0 +1,17 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle')
+
+## OracleConnectionOptionsBuilder Class
+
+Specifies options for connecting to and locking against an Oracle database
+
+```csharp
+public sealed class OracleConnectionOptionsBuilder
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 OracleConnectionOptionsBuilder
+
+| Methods | |
+| :--- | :--- |
+| [KeepaliveCadence(TimeSpan)](OracleConnectionOptionsBuilder.KeepaliveCadence.cpYoNdk/QhqJGH/58Hukqw.md 'Medallion.Threading.Oracle.OracleConnectionOptionsBuilder.KeepaliveCadence(System.TimeSpan)') | Oracle does not kill idle connections by default, so by default keepalive is disabled (set to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')). However, if you are using the IDLE_TIME setting in Oracle or if your network is dropping connections that are idle holding locks for a long time, you can set a value for keepalive to prevent this from happening. See https://stackoverflow.com/questions/1966247/idle-timeout-parameter-in-oracle. |
+| [UseMultiplexing(bool)](OracleConnectionOptionsBuilder.UseMultiplexing.A+iIKatFl3VDvz/7Q6X3Jg.md 'Medallion.Threading.Oracle.OracleConnectionOptionsBuilder.UseMultiplexing(bool)') | This mode takes advantage of the fact that while "holding" a lock (or other synchronization primitive) a connection is essentially idle. Thus, rather than creating a new connection for each held lock it is often possible to multiplex a shared connection so that that connection can hold multiple locks at the same time. Multiplexing is on by default. This is implemented in such a way that releasing a lock held on such a connection will never be blocked by an Acquire() call that is waiting to acquire a lock on that same connection. For this reason, the multiplexing strategy is "optimistic": if the lock can't be acquired instantaneously on the shared connection, a new (shareable) connection will be allocated. This option can improve performance and avoid connection pool starvation in high-load scenarios. It is also particularly applicable to cases where [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)') semantics are used with a zero-length timeout. |
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md b/docs/api/DistributedLock.Oracle/OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md
new file mode 100644
index 00000000..d463b5b5
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md
@@ -0,0 +1,30 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock')
+
+## OracleDistributedLock(string, string, Action, bool) Constructor
+
+Constructs a lock with the given [name](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).name 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool).name') that connects using the provided [connectionString](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).connectionString 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool).connectionString') and
+[options](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).options 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool).options').
+
+Unless [exactName](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool).exactName') is specified, [name](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).name 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool).name') will be escaped/hashed to ensure name validity.
+
+```csharp
+public OracleDistributedLock(string name, string connectionString, System.Action? options=null, bool exactName=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`connectionString` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`options` [System.Action<](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')[OracleConnectionOptionsBuilder](OracleConnectionOptionsBuilder.md 'Medallion.Threading.Oracle.OracleConnectionOptionsBuilder')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')
+
+
+
+`exactName` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md b/docs/api/DistributedLock.Oracle/OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md
new file mode 100644
index 00000000..5a1db908
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md
@@ -0,0 +1,25 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock')
+
+## OracleDistributedLock(string, IDbConnection, bool) Constructor
+
+Constructs a lock with the given [name](OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, System.Data.IDbConnection, bool).name') that connects using the provided [connection](OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,System.Data.IDbConnection,bool).connection 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, System.Data.IDbConnection, bool).connection').
+
+Unless [exactName](OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,System.Data.IDbConnection,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, System.Data.IDbConnection, bool).exactName') is specified, [name](OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, System.Data.IDbConnection, bool).name') will be escaped/hashed to ensure name validity.
+
+```csharp
+public OracleDistributedLock(string name, System.Data.IDbConnection connection, bool exactName=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`connection` [System.Data.IDbConnection](https://docs.microsoft.com/en-us/dotnet/api/System.Data.IDbConnection 'System.Data.IDbConnection')
+
+
+
+`exactName` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLock.Acquire.+4c1n2Rm+XfIwQt9S5GCNA.md b/docs/api/DistributedLock.Oracle/OracleDistributedLock.Acquire.+4c1n2Rm+XfIwQt9S5GCNA.md
new file mode 100644
index 00000000..5baab860
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLock.Acquire.+4c1n2Rm+XfIwQt9S5GCNA.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock')
+
+## OracleDistributedLock.Acquire(Nullable, CancellationToken) Method
+
+Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+using (myLock.Acquire(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public Medallion.Threading.Oracle.OracleDistributedLockHandle Acquire(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [Acquire(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md 'Medallion.Threading.IDistributedLock.Acquire(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle')
+An [OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLock.AcquireAsync.DWy8bDbjQOspqGdARG5H5Q.md b/docs/api/DistributedLock.Oracle/OracleDistributedLock.AcquireAsync.DWy8bDbjQOspqGdARG5H5Q.md
new file mode 100644
index 00000000..8e85142d
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLock.AcquireAsync.DWy8bDbjQOspqGdARG5H5Q.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock')
+
+## OracleDistributedLock.AcquireAsync(Nullable, CancellationToken) Method
+
+Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+await using (await myLock.AcquireAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask AcquireAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md 'Medallion.Threading.IDistributedLock.AcquireAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLock.Name.md b/docs/api/DistributedLock.Oracle/OracleDistributedLock.Name.md
new file mode 100644
index 00000000..7a2bdeb9
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLock.Name.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock')
+
+## OracleDistributedLock.Name Property
+
+Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name')
+
+```csharp
+public string Name { get; }
+```
+
+Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name')
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLock.TryAcquire.jxpTPDKrpAohkKglVpscdw.md b/docs/api/DistributedLock.Oracle/OracleDistributedLock.TryAcquire.jxpTPDKrpAohkKglVpscdw.md
new file mode 100644
index 00000000..d220f837
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLock.TryAcquire.jxpTPDKrpAohkKglVpscdw.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock')
+
+## OracleDistributedLock.TryAcquire(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock synchronously. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquire(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public Medallion.Threading.Oracle.OracleDistributedLockHandle? TryAcquire(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle')
+An [OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLock.TryAcquireAsync.2c/SHuju3pt92jk0aHMPqQ.md b/docs/api/DistributedLock.Oracle/OracleDistributedLock.TryAcquireAsync.2c/SHuju3pt92jk0aHMPqQ.md
new file mode 100644
index 00000000..4fa40f0b
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLock.TryAcquireAsync.2c/SHuju3pt92jk0aHMPqQ.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock')
+
+## OracleDistributedLock.TryAcquireAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock asynchronously. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask TryAcquireAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md 'Medallion.Threading.IDistributedLock.TryAcquireAsync(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLock.md b/docs/api/DistributedLock.Oracle/OracleDistributedLock.md
new file mode 100644
index 00000000..f13c7b81
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLock.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle')
+
+## OracleDistributedLock Class
+
+Implements a distributed lock for Oracle databse based on the DBMS_LOCK package
+
+```csharp
+public sealed class OracleDistributedLock :
+Medallion.Threading.IDistributedLock
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 OracleDistributedLock
+
+Implements [IDistributedLock](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.md 'Medallion.Threading.IDistributedLock')
+
+| Constructors | |
+| :--- | :--- |
+| [OracleDistributedLock(string, string, Action<OracleConnectionOptionsBuilder>, bool)](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool)') | Constructs a lock with the given [name](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).name 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool).name') that connects using the provided [connectionString](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).connectionString 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool).connectionString') and [options](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).options 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool).options'). Unless [exactName](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool).exactName') is specified, [name](OracleDistributedLock..ctor.2/b645uSsJRoN1RGNqS0EQ.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).name 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, string, System.Action, bool).name') will be escaped/hashed to ensure name validity. |
+| [OracleDistributedLock(string, IDbConnection, bool)](OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, System.Data.IDbConnection, bool)') | Constructs a lock with the given [name](OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, System.Data.IDbConnection, bool).name') that connects using the provided [connection](OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,System.Data.IDbConnection,bool).connection 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, System.Data.IDbConnection, bool).connection'). Unless [exactName](OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,System.Data.IDbConnection,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, System.Data.IDbConnection, bool).exactName') is specified, [name](OracleDistributedLock..ctor.ruFnlqTt8A/yRSLZE0t3dA.md#Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.Oracle.OracleDistributedLock.OracleDistributedLock(string, System.Data.IDbConnection, bool).name') will be escaped/hashed to ensure name validity. |
+
+| Properties | |
+| :--- | :--- |
+| [Name](OracleDistributedLock.Name.md 'Medallion.Threading.Oracle.OracleDistributedLock.Name') | Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name') |
+
+| Methods | |
+| :--- | :--- |
+| [Acquire(Nullable<TimeSpan>, CancellationToken)](OracleDistributedLock.Acquire.+4c1n2Rm+XfIwQt9S5GCNA.md 'Medallion.Threading.Oracle.OracleDistributedLock.Acquire(System.Nullable, System.Threading.CancellationToken)') | Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](OracleDistributedLock.AcquireAsync.DWy8bDbjQOspqGdARG5H5Q.md 'Medallion.Threading.Oracle.OracleDistributedLock.AcquireAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage: |
+| [TryAcquire(TimeSpan, CancellationToken)](OracleDistributedLock.TryAcquire.jxpTPDKrpAohkKglVpscdw.md 'Medallion.Threading.Oracle.OracleDistributedLock.TryAcquire(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire the lock synchronously. Usage: |
+| [TryAcquireAsync(TimeSpan, CancellationToken)](OracleDistributedLock.TryAcquireAsync.2c/SHuju3pt92jk0aHMPqQ.md 'Medallion.Threading.Oracle.OracleDistributedLock.TryAcquireAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire the lock asynchronously. Usage: |
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.Dispose().md b/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.Dispose().md
new file mode 100644
index 00000000..42d911f6
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.Dispose().md
@@ -0,0 +1,12 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle')
+
+## OracleDistributedLockHandle.Dispose() Method
+
+Releases the lock
+
+```csharp
+public void Dispose();
+```
+
+Implements [Dispose()](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable.Dispose 'System.IDisposable.Dispose')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.DisposeAsync().md b/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.DisposeAsync().md
new file mode 100644
index 00000000..c91138fd
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.DisposeAsync().md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle')
+
+## OracleDistributedLockHandle.DisposeAsync() Method
+
+Releases the lock asynchronously
+
+```csharp
+public System.Threading.Tasks.ValueTask DisposeAsync();
+```
+
+Implements [DisposeAsync()](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable.DisposeAsync 'System.IAsyncDisposable.DisposeAsync')
+
+#### Returns
+[System.Threading.Tasks.ValueTask](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask 'System.Threading.Tasks.ValueTask')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.HandleLostToken.md b/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.HandleLostToken.md
new file mode 100644
index 00000000..7e8d3c6a
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.HandleLostToken.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedLockHandle](OracleDistributedLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle')
+
+## OracleDistributedLockHandle.HandleLostToken Property
+
+Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken')
+
+```csharp
+public System.Threading.CancellationToken HandleLostToken { get; }
+```
+
+Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken')
+
+#### Property Value
+[System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.md b/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.md
new file mode 100644
index 00000000..c6e71550
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedLockHandle.md
@@ -0,0 +1,26 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle')
+
+## OracleDistributedLockHandle Class
+
+Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+
+```csharp
+public sealed class OracleDistributedLockHandle :
+Medallion.Threading.IDistributedSynchronizationHandle,
+System.IDisposable,
+System.IAsyncDisposable
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 OracleDistributedLockHandle
+
+Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle'), [System.IDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable 'System.IDisposable'), [System.IAsyncDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable 'System.IAsyncDisposable')
+
+| Properties | |
+| :--- | :--- |
+| [HandleLostToken](OracleDistributedLockHandle.HandleLostToken.md 'Medallion.Threading.Oracle.OracleDistributedLockHandle.HandleLostToken') | Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken') |
+
+| Methods | |
+| :--- | :--- |
+| [Dispose()](OracleDistributedLockHandle.Dispose().md 'Medallion.Threading.Oracle.OracleDistributedLockHandle.Dispose()') | Releases the lock |
+| [DisposeAsync()](OracleDistributedLockHandle.DisposeAsync().md 'Medallion.Threading.Oracle.OracleDistributedLockHandle.DisposeAsync()') | Releases the lock asynchronously |
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md
new file mode 100644
index 00000000..385edc71
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock(string, string, Action, bool) Constructor
+
+Constructs a new lock using the provided [name](OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).name 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, string, System.Action, bool).name').
+
+The provided [connectionString](OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).connectionString 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, string, System.Action, bool).connectionString') will be used to connect to the database.
+
+Unless [exactName](OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, string, System.Action, bool).exactName') is specified, [name](OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).name 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, string, System.Action, bool).name') will be escaped/hashed to ensure name validity.
+
+```csharp
+public OracleDistributedReaderWriterLock(string name, string connectionString, System.Action? options=null, bool exactName=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`connectionString` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`options` [System.Action<](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')[OracleConnectionOptionsBuilder](OracleConnectionOptionsBuilder.md 'Medallion.Threading.Oracle.OracleConnectionOptionsBuilder')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')
+
+
+
+`exactName` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md
new file mode 100644
index 00000000..3739ec83
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md
@@ -0,0 +1,28 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock(string, IDbConnection, bool) Constructor
+
+Constructs a new lock using the provided [name](OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, System.Data.IDbConnection, bool).name').
+
+The provided [connection](OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,System.Data.IDbConnection,bool).connection 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, System.Data.IDbConnection, bool).connection') will be used to connect to the database and will provide lock scope. It is assumed to be externally managed and
+will not be opened or closed.
+
+Unless [exactName](OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,System.Data.IDbConnection,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, System.Data.IDbConnection, bool).exactName') is specified, [name](OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, System.Data.IDbConnection, bool).name') will be escaped/hashed to ensure name validity.
+
+```csharp
+public OracleDistributedReaderWriterLock(string name, System.Data.IDbConnection connection, bool exactName=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`connection` [System.Data.IDbConnection](https://docs.microsoft.com/en-us/dotnet/api/System.Data.IDbConnection 'System.Data.IDbConnection')
+
+
+
+`exactName` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireReadLock.i+1DmU9e9egRXs1g6b3Gpw.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireReadLock.i+1DmU9e9egRXs1g6b3Gpw.md
new file mode 100644
index 00000000..4b6b0bbc
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireReadLock.i+1DmU9e9egRXs1g6b3Gpw.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.AcquireReadLock(Nullable, CancellationToken) Method
+
+Acquires a READ lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Multiple readers are allowed. Not compatible with a WRITE lock. Usage:
+
+```csharp
+using (myLock.AcquireReadLock(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle AcquireReadLock(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireReadLock(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireReadLock.bAhgltfPpI+hi4bNotiyGg.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireReadLock(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')
+An [OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireReadLockAsync.cHH807x/OmDfG5O0jJHDbg.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireReadLockAsync.cHH807x/OmDfG5O0jJHDbg.md
new file mode 100644
index 00000000..de647c7c
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireReadLockAsync.cHH807x/OmDfG5O0jJHDbg.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.AcquireReadLockAsync(Nullable, CancellationToken) Method
+
+Acquires a READ lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Multiple readers are allowed. Not compatible with a WRITE lock. Usage:
+
+```csharp
+await using (await myLock.AcquireReadLockAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask AcquireReadLockAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireReadLockAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireReadLockAsync.otuQSEhQpAEqEEBnyFJHtw.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireReadLockAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireUpgradeableReadLock.R7oQaBTKIoxOXrOAlSXjVw.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireUpgradeableReadLock.R7oQaBTKIoxOXrOAlSXjVw.md
new file mode 100644
index 00000000..2920e431
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireUpgradeableReadLock.R7oQaBTKIoxOXrOAlSXjVw.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.AcquireUpgradeableReadLock(Nullable, CancellationToken) Method
+
+Acquires an UPGRADE lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another UPGRADE lock or a WRITE lock. Usage:
+
+```csharp
+using (myLock.AcquireUpgradeableReadLock(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle AcquireUpgradeableReadLock(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireUpgradeableReadLock(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock.MgsbqNeNv0qen0RVQV8MHA.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLock(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')
+An [OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireUpgradeableReadLockAsync.ResKtbEYMnwtBr+1n8rCVA.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireUpgradeableReadLockAsync.ResKtbEYMnwtBr+1n8rCVA.md
new file mode 100644
index 00000000..4545197a
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireUpgradeableReadLockAsync.ResKtbEYMnwtBr+1n8rCVA.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.AcquireUpgradeableReadLockAsync(Nullable, CancellationToken) Method
+
+Acquires an UPGRADE lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another UPGRADE lock or a WRITE lock. Usage:
+
+```csharp
+await using (await myLock.AcquireUpgradeableReadLockAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask AcquireUpgradeableReadLockAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireUpgradeableReadLockAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync.XDD/LbfIJrScMNU14D5OvA.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.AcquireUpgradeableReadLockAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireWriteLock.EHh6icCC0sW+KpPfQpbkqw.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireWriteLock.EHh6icCC0sW+KpPfQpbkqw.md
new file mode 100644
index 00000000..07e28e96
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireWriteLock.EHh6icCC0sW+KpPfQpbkqw.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.AcquireWriteLock(Nullable, CancellationToken) Method
+
+Acquires a WRITE lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another WRITE lock or an UPGRADE lock. Usage:
+
+```csharp
+using (myLock.AcquireWriteLock(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle AcquireWriteLock(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireWriteLock(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireWriteLock.8zDirrYDrgr0WzrsnH7blA.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireWriteLock(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')
+An [OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireWriteLockAsync.i6hqw6JHp5wzxI8GbW0daA.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireWriteLockAsync.i6hqw6JHp5wzxI8GbW0daA.md
new file mode 100644
index 00000000..a116b58d
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.AcquireWriteLockAsync.i6hqw6JHp5wzxI8GbW0daA.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.AcquireWriteLockAsync(Nullable, CancellationToken) Method
+
+Acquires a WRITE lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another WRITE lock or an UPGRADE lock. Usage:
+
+```csharp
+await using (await myLock.AcquireWriteLockAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask AcquireWriteLockAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireWriteLockAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.AcquireWriteLockAsync.fFyCc0HswQXUnGvjzNHJ+A.md 'Medallion.Threading.IDistributedReaderWriterLock.AcquireWriteLockAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.Name.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.Name.md
new file mode 100644
index 00000000..40398a0f
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.Name.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.Name Property
+
+Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name')
+
+```csharp
+public string Name { get; }
+```
+
+Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.Name.md 'Medallion.Threading.IDistributedReaderWriterLock.Name')
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireReadLock.hJ8GIzamtceZzMUxp70TPQ.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireReadLock.hJ8GIzamtceZzMUxp70TPQ.md
new file mode 100644
index 00000000..b7c87198
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireReadLock.hJ8GIzamtceZzMUxp70TPQ.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.TryAcquireReadLock(TimeSpan, CancellationToken) Method
+
+Attempts to acquire a READ lock synchronously. Multiple readers are allowed. Not compatible with a WRITE lock. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquireReadLock(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle? TryAcquireReadLock(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireReadLock(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireReadLock.FwhFBAUmx9brWLKd6O1SSw.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireReadLock(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')
+An [OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireReadLockAsync.IEoPoW7dEaZKcc46gq1JiQ.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireReadLockAsync.IEoPoW7dEaZKcc46gq1JiQ.md
new file mode 100644
index 00000000..a04a8ee9
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireReadLockAsync.IEoPoW7dEaZKcc46gq1JiQ.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.TryAcquireReadLockAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire a READ lock asynchronously. Multiple readers are allowed. Not compatible with a WRITE lock. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireReadLockAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask TryAcquireReadLockAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireReadLockAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireReadLockAsync.1wx2S+CeVe62/fKwnr3rNQ.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireReadLockAsync(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLock.pCah2aRljYOlO0JIWgorWA.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLock.pCah2aRljYOlO0JIWgorWA.md
new file mode 100644
index 00000000..918e58fb
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLock.pCah2aRljYOlO0JIWgorWA.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLock(TimeSpan, CancellationToken) Method
+
+Attempts to acquire an UPGRADE lock synchronously. Not compatible with another UPGRADE lock or a WRITE lock. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquireUpgradeableReadLock(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle? TryAcquireUpgradeableReadLock(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireUpgradeableReadLock(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock.NcomTiK4v4VsrD5p8zrY6A.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLock(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')
+An [OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLockAsync.21/n2EnWZfs+furVMXeXQ.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLockAsync.21/n2EnWZfs+furVMXeXQ.md
new file mode 100644
index 00000000..d3af15cb
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLockAsync.21/n2EnWZfs+furVMXeXQ.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLockAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire an UPGRADE lock asynchronously. Not compatible with another UPGRADE lock or a WRITE lock. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireUpgradeableReadLockAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask TryAcquireUpgradeableReadLockAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireUpgradeableReadLockAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync.NeQQ4jMkCO0IteXQSJv/1w.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock.TryAcquireUpgradeableReadLockAsync(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireWriteLock.z52QOCPLLTcPg/Rkv1mHYQ.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireWriteLock.z52QOCPLLTcPg/Rkv1mHYQ.md
new file mode 100644
index 00000000..3c5cbe63
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireWriteLock.z52QOCPLLTcPg/Rkv1mHYQ.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.TryAcquireWriteLock(TimeSpan, CancellationToken) Method
+
+Attempts to acquire a WRITE lock synchronously. Not compatible with another WRITE lock or an UPGRADE lock. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquireWriteLock(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle? TryAcquireWriteLock(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireWriteLock(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireWriteLock.ypAYPzEP3B1U6LcOEQzWBw.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireWriteLock(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')
+An [OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireWriteLockAsync.N34kqc/h8laY2Ll0B3qHLA.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireWriteLockAsync.N34kqc/h8laY2Ll0B3qHLA.md
new file mode 100644
index 00000000..42a36a7a
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.TryAcquireWriteLockAsync.N34kqc/h8laY2Ll0B3qHLA.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+## OracleDistributedReaderWriterLock.TryAcquireWriteLockAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire a WRITE lock asynchronously. Not compatible with another WRITE lock or an UPGRADE lock. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireWriteLockAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask TryAcquireWriteLockAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireWriteLockAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.TryAcquireWriteLockAsync.yhTsitSwERpacPdxWmUvww.md 'Medallion.Threading.IDistributedReaderWriterLock.TryAcquireWriteLockAsync(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+An [OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.md
new file mode 100644
index 00000000..2618aa71
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLock.md
@@ -0,0 +1,40 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle')
+
+## OracleDistributedReaderWriterLock Class
+
+Implements an upgradeable distributed reader-writer lock for the Oracle database using the DBMS_LOCK package.
+
+```csharp
+public sealed class OracleDistributedReaderWriterLock :
+Medallion.Threading.IDistributedUpgradeableReaderWriterLock,
+Medallion.Threading.IDistributedReaderWriterLock
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 OracleDistributedReaderWriterLock
+
+Implements [IDistributedUpgradeableReaderWriterLock](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLock.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLock'), [IDistributedReaderWriterLock](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLock.md 'Medallion.Threading.IDistributedReaderWriterLock')
+
+| Constructors | |
+| :--- | :--- |
+| [OracleDistributedReaderWriterLock(string, string, Action<OracleConnectionOptionsBuilder>, bool)](OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, string, System.Action, bool)') | Constructs a new lock using the provided [name](OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).name 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, string, System.Action, bool).name'). The provided [connectionString](OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).connectionString 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, string, System.Action, bool).connectionString') will be used to connect to the database. Unless [exactName](OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, string, System.Action, bool).exactName') is specified, [name](OracleDistributedReaderWriterLock..ctor.8lBF247l20W+SBlWEwdqmQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_,bool).name 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, string, System.Action, bool).name') will be escaped/hashed to ensure name validity. |
+| [OracleDistributedReaderWriterLock(string, IDbConnection, bool)](OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, System.Data.IDbConnection, bool)') | Constructs a new lock using the provided [name](OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, System.Data.IDbConnection, bool).name'). The provided [connection](OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,System.Data.IDbConnection,bool).connection 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, System.Data.IDbConnection, bool).connection') will be used to connect to the database and will provide lock scope. It is assumed to be externally managed and will not be opened or closed. Unless [exactName](OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,System.Data.IDbConnection,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, System.Data.IDbConnection, bool).exactName') is specified, [name](OracleDistributedReaderWriterLock..ctor.JHJcHUumz9o6mcMVD9M0SQ.md#Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string,System.Data.IDbConnection,bool).name 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.OracleDistributedReaderWriterLock(string, System.Data.IDbConnection, bool).name') will be escaped/hashed to ensure name validity. |
+
+| Properties | |
+| :--- | :--- |
+| [Name](OracleDistributedReaderWriterLock.Name.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.Name') | Implements [Name](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Name.md 'Medallion.Threading.IDistributedLock.Name') |
+
+| Methods | |
+| :--- | :--- |
+| [AcquireReadLock(Nullable<TimeSpan>, CancellationToken)](OracleDistributedReaderWriterLock.AcquireReadLock.i+1DmU9e9egRXs1g6b3Gpw.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.AcquireReadLock(System.Nullable, System.Threading.CancellationToken)') | Acquires a READ lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Multiple readers are allowed. Not compatible with a WRITE lock. Usage: |
+| [AcquireReadLockAsync(Nullable<TimeSpan>, CancellationToken)](OracleDistributedReaderWriterLock.AcquireReadLockAsync.cHH807x/OmDfG5O0jJHDbg.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.AcquireReadLockAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires a READ lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Multiple readers are allowed. Not compatible with a WRITE lock. Usage: |
+| [AcquireUpgradeableReadLock(Nullable<TimeSpan>, CancellationToken)](OracleDistributedReaderWriterLock.AcquireUpgradeableReadLock.R7oQaBTKIoxOXrOAlSXjVw.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.AcquireUpgradeableReadLock(System.Nullable, System.Threading.CancellationToken)') | Acquires an UPGRADE lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another UPGRADE lock or a WRITE lock. Usage: |
+| [AcquireUpgradeableReadLockAsync(Nullable<TimeSpan>, CancellationToken)](OracleDistributedReaderWriterLock.AcquireUpgradeableReadLockAsync.ResKtbEYMnwtBr+1n8rCVA.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.AcquireUpgradeableReadLockAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires an UPGRADE lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another UPGRADE lock or a WRITE lock. Usage: |
+| [AcquireWriteLock(Nullable<TimeSpan>, CancellationToken)](OracleDistributedReaderWriterLock.AcquireWriteLock.EHh6icCC0sW+KpPfQpbkqw.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.AcquireWriteLock(System.Nullable, System.Threading.CancellationToken)') | Acquires a WRITE lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another WRITE lock or an UPGRADE lock. Usage: |
+| [AcquireWriteLockAsync(Nullable<TimeSpan>, CancellationToken)](OracleDistributedReaderWriterLock.AcquireWriteLockAsync.i6hqw6JHp5wzxI8GbW0daA.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.AcquireWriteLockAsync(System.Nullable, System.Threading.CancellationToken)') | Acquires a WRITE lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Not compatible with another WRITE lock or an UPGRADE lock. Usage: |
+| [TryAcquireReadLock(TimeSpan, CancellationToken)](OracleDistributedReaderWriterLock.TryAcquireReadLock.hJ8GIzamtceZzMUxp70TPQ.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.TryAcquireReadLock(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire a READ lock synchronously. Multiple readers are allowed. Not compatible with a WRITE lock. Usage: |
+| [TryAcquireReadLockAsync(TimeSpan, CancellationToken)](OracleDistributedReaderWriterLock.TryAcquireReadLockAsync.IEoPoW7dEaZKcc46gq1JiQ.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.TryAcquireReadLockAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire a READ lock asynchronously. Multiple readers are allowed. Not compatible with a WRITE lock. Usage: |
+| [TryAcquireUpgradeableReadLock(TimeSpan, CancellationToken)](OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLock.pCah2aRljYOlO0JIWgorWA.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLock(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire an UPGRADE lock synchronously. Not compatible with another UPGRADE lock or a WRITE lock. Usage: |
+| [TryAcquireUpgradeableReadLockAsync(TimeSpan, CancellationToken)](OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLockAsync.21//n2EnWZfs+furVMXeXQ.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.TryAcquireUpgradeableReadLockAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire an UPGRADE lock asynchronously. Not compatible with another UPGRADE lock or a WRITE lock. Usage: |
+| [TryAcquireWriteLock(TimeSpan, CancellationToken)](OracleDistributedReaderWriterLock.TryAcquireWriteLock.z52QOCPLLTcPg/Rkv1mHYQ.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.TryAcquireWriteLock(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire a WRITE lock synchronously. Not compatible with another WRITE lock or an UPGRADE lock. Usage: |
+| [TryAcquireWriteLockAsync(TimeSpan, CancellationToken)](OracleDistributedReaderWriterLock.TryAcquireWriteLockAsync.N34kqc/h8laY2Ll0B3qHLA.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock.TryAcquireWriteLockAsync(System.TimeSpan, System.Threading.CancellationToken)') | Attempts to acquire a WRITE lock asynchronously. Not compatible with another WRITE lock or an UPGRADE lock. Usage: |
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.Dispose().md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.Dispose().md
new file mode 100644
index 00000000..cf848f09
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.Dispose().md
@@ -0,0 +1,12 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')
+
+## OracleDistributedReaderWriterLockHandle.Dispose() Method
+
+Releases the lock
+
+```csharp
+public void Dispose();
+```
+
+Implements [Dispose()](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable.Dispose 'System.IDisposable.Dispose')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.DisposeAsync().md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.DisposeAsync().md
new file mode 100644
index 00000000..7a69f104
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.DisposeAsync().md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')
+
+## OracleDistributedReaderWriterLockHandle.DisposeAsync() Method
+
+Releases the lock asynchronously
+
+```csharp
+public abstract System.Threading.Tasks.ValueTask DisposeAsync();
+```
+
+Implements [DisposeAsync()](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable.DisposeAsync 'System.IAsyncDisposable.DisposeAsync')
+
+#### Returns
+[System.Threading.Tasks.ValueTask](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask 'System.Threading.Tasks.ValueTask')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.HandleLostToken.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.HandleLostToken.md
new file mode 100644
index 00000000..91231bb5
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.HandleLostToken.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle')
+
+## OracleDistributedReaderWriterLockHandle.HandleLostToken Property
+
+Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken')
+
+```csharp
+public abstract System.Threading.CancellationToken HandleLostToken { get; }
+```
+
+Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken')
+
+#### Property Value
+[System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.md
new file mode 100644
index 00000000..b644fb91
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockHandle.md
@@ -0,0 +1,29 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle')
+
+## OracleDistributedReaderWriterLockHandle Class
+
+Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle')
+
+```csharp
+public abstract class OracleDistributedReaderWriterLockHandle :
+Medallion.Threading.IDistributedSynchronizationHandle,
+System.IDisposable,
+System.IAsyncDisposable
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 OracleDistributedReaderWriterLockHandle
+
+Derived
+↳ [OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')
+
+Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle'), [System.IDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable 'System.IDisposable'), [System.IAsyncDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable 'System.IAsyncDisposable')
+
+| Properties | |
+| :--- | :--- |
+| [HandleLostToken](OracleDistributedReaderWriterLockHandle.HandleLostToken.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle.HandleLostToken') | Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken') |
+
+| Methods | |
+| :--- | :--- |
+| [Dispose()](OracleDistributedReaderWriterLockHandle.Dispose().md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle.Dispose()') | Releases the lock |
+| [DisposeAsync()](OracleDistributedReaderWriterLockHandle.DisposeAsync().md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle.DisposeAsync()') | Releases the lock asynchronously |
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.DisposeAsync().md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.DisposeAsync().md
new file mode 100644
index 00000000..e62a48d3
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.DisposeAsync().md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')
+
+## OracleDistributedReaderWriterLockUpgradeableHandle.DisposeAsync() Method
+
+Releases the lock asynchronously
+
+```csharp
+public override System.Threading.Tasks.ValueTask DisposeAsync();
+```
+
+Implements [DisposeAsync()](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable.DisposeAsync 'System.IAsyncDisposable.DisposeAsync')
+
+#### Returns
+[System.Threading.Tasks.ValueTask](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask 'System.Threading.Tasks.ValueTask')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.HandleLostToken.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.HandleLostToken.md
new file mode 100644
index 00000000..80a4156d
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.HandleLostToken.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')
+
+## OracleDistributedReaderWriterLockUpgradeableHandle.HandleLostToken Property
+
+Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken')
+
+```csharp
+public override System.Threading.CancellationToken HandleLostToken { get; }
+```
+
+Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken')
+
+#### Property Value
+[System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLock/jHol+SIt7DlqMKC8v111g.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLock/jHol+SIt7DlqMKC8v111g.md
new file mode 100644
index 00000000..260ee3d2
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLock/jHol+SIt7DlqMKC8v111g.md
@@ -0,0 +1,24 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')
+
+## OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLock(TimeSpan, CancellationToken) Method
+
+Implements [TryUpgradeToWriteLock(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock.kj/tM1emIKPQTMhyxJaEVg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock(System.TimeSpan,System.Threading.CancellationToken)')
+
+```csharp
+public bool TryUpgradeToWriteLock(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Implements [TryUpgradeToWriteLock(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock.kj/tM1emIKPQTMhyxJaEVg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLockAsync.FgoBDmLlHiktYNvHXL6NPw.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLockAsync.FgoBDmLlHiktYNvHXL6NPw.md
new file mode 100644
index 00000000..d209e812
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLockAsync.FgoBDmLlHiktYNvHXL6NPw.md
@@ -0,0 +1,24 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')
+
+## OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLockAsync(TimeSpan, CancellationToken) Method
+
+Implements [TryUpgradeToWriteLockAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync.wN/ZfUBdRwlMtX9ctB9dtg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync(System.TimeSpan,System.Threading.CancellationToken)')
+
+```csharp
+public System.Threading.Tasks.ValueTask TryUpgradeToWriteLockAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Implements [TryUpgradeToWriteLockAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync.wN/ZfUBdRwlMtX9ctB9dtg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLock.hWqwyiLC1304nrfXA65g6A.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLock.hWqwyiLC1304nrfXA65g6A.md
new file mode 100644
index 00000000..9b4e1fcd
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLock.hWqwyiLC1304nrfXA65g6A.md
@@ -0,0 +1,21 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')
+
+## OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLock(Nullable, CancellationToken) Method
+
+Implements [UpgradeToWriteLock(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLock.Tz7MsKLra+HymbjqGwuzRQ.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.UpgradeToWriteLock(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+```csharp
+public void UpgradeToWriteLock(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Implements [UpgradeToWriteLock(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLock.Tz7MsKLra+HymbjqGwuzRQ.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.UpgradeToWriteLock(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLockAsync.NiMBlMvyOdtLajlwUeLO1Q.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLockAsync.NiMBlMvyOdtLajlwUeLO1Q.md
new file mode 100644
index 00000000..8708a12d
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLockAsync.NiMBlMvyOdtLajlwUeLO1Q.md
@@ -0,0 +1,24 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedReaderWriterLockUpgradeableHandle](OracleDistributedReaderWriterLockUpgradeableHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle')
+
+## OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLockAsync(Nullable, CancellationToken) Method
+
+Implements [UpgradeToWriteLockAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync.5X2Faf/VtyA3b0uF1JN1kg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+```csharp
+public System.Threading.Tasks.ValueTask UpgradeToWriteLockAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Implements [UpgradeToWriteLockAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync.5X2Faf/VtyA3b0uF1JN1kg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask 'System.Threading.Tasks.ValueTask')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.md b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.md
new file mode 100644
index 00000000..bc846184
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedReaderWriterLockUpgradeableHandle.md
@@ -0,0 +1,30 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle')
+
+## OracleDistributedReaderWriterLockUpgradeableHandle Class
+
+Implements [IDistributedLockUpgradeableHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle')
+
+```csharp
+public sealed class OracleDistributedReaderWriterLockUpgradeableHandle : Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle,
+Medallion.Threading.IDistributedLockUpgradeableHandle,
+Medallion.Threading.IDistributedSynchronizationHandle,
+System.IDisposable,
+System.IAsyncDisposable
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 [OracleDistributedReaderWriterLockHandle](OracleDistributedReaderWriterLockHandle.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockHandle') 🡒 OracleDistributedReaderWriterLockUpgradeableHandle
+
+Implements [IDistributedLockUpgradeableHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.md 'Medallion.Threading.IDistributedLockUpgradeableHandle'), [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle'), [System.IDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IDisposable 'System.IDisposable'), [System.IAsyncDisposable](https://docs.microsoft.com/en-us/dotnet/api/System.IAsyncDisposable 'System.IAsyncDisposable')
+
+| Properties | |
+| :--- | :--- |
+| [HandleLostToken](OracleDistributedReaderWriterLockUpgradeableHandle.HandleLostToken.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle.HandleLostToken') | Implements [HandleLostToken](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.HandleLostToken.md 'Medallion.Threading.IDistributedSynchronizationHandle.HandleLostToken') |
+
+| Methods | |
+| :--- | :--- |
+| [DisposeAsync()](OracleDistributedReaderWriterLockUpgradeableHandle.DisposeAsync().md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle.DisposeAsync()') | Releases the lock asynchronously |
+| [TryUpgradeToWriteLock(TimeSpan, CancellationToken)](OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLock./jHol+SIt7DlqMKC8v111g.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLock(System.TimeSpan, System.Threading.CancellationToken)') | Implements [TryUpgradeToWriteLock(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock.kj/tM1emIKPQTMhyxJaEVg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.TryUpgradeToWriteLock(System.TimeSpan,System.Threading.CancellationToken)') |
+| [TryUpgradeToWriteLockAsync(TimeSpan, CancellationToken)](OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLockAsync.FgoBDmLlHiktYNvHXL6NPw.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle.TryUpgradeToWriteLockAsync(System.TimeSpan, System.Threading.CancellationToken)') | Implements [TryUpgradeToWriteLockAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync.wN/ZfUBdRwlMtX9ctB9dtg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.TryUpgradeToWriteLockAsync(System.TimeSpan,System.Threading.CancellationToken)') |
+| [UpgradeToWriteLock(Nullable<TimeSpan>, CancellationToken)](OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLock.hWqwyiLC1304nrfXA65g6A.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLock(System.Nullable, System.Threading.CancellationToken)') | Implements [UpgradeToWriteLock(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLock.Tz7MsKLra+HymbjqGwuzRQ.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.UpgradeToWriteLock(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)') |
+| [UpgradeToWriteLockAsync(Nullable<TimeSpan>, CancellationToken)](OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLockAsync.NiMBlMvyOdtLajlwUeLO1Q.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLockUpgradeableHandle.UpgradeToWriteLockAsync(System.Nullable, System.Threading.CancellationToken)') | Implements [UpgradeToWriteLockAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync.5X2Faf/VtyA3b0uF1JN1kg.md 'Medallion.Threading.IDistributedLockUpgradeableHandle.UpgradeToWriteLockAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)') |
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider..ctor.Vs3QzXeKG/WYsARra1TfMA.md b/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider..ctor.Vs3QzXeKG/WYsARra1TfMA.md
new file mode 100644
index 00000000..741ae486
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider..ctor.Vs3QzXeKG/WYsARra1TfMA.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedSynchronizationProvider](OracleDistributedSynchronizationProvider.md 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider')
+
+## OracleDistributedSynchronizationProvider(string, Action) Constructor
+
+Constructs a provider that connects with [connectionString](OracleDistributedSynchronizationProvider..ctor.Vs3QzXeKG/WYsARra1TfMA.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_).connectionString 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(string, System.Action).connectionString') and [options](OracleDistributedSynchronizationProvider..ctor.Vs3QzXeKG/WYsARra1TfMA.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_).options 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(string, System.Action).options').
+
+```csharp
+public OracleDistributedSynchronizationProvider(string connectionString, System.Action? options=null);
+```
+#### Parameters
+
+
+
+`connectionString` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`options` [System.Action<](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')[OracleConnectionOptionsBuilder](OracleConnectionOptionsBuilder.md 'Medallion.Threading.Oracle.OracleConnectionOptionsBuilder')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider..ctor.piz12qaqFtocRjH6VWNIGQ.md b/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider..ctor.piz12qaqFtocRjH6VWNIGQ.md
new file mode 100644
index 00000000..3874d916
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider..ctor.piz12qaqFtocRjH6VWNIGQ.md
@@ -0,0 +1,15 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedSynchronizationProvider](OracleDistributedSynchronizationProvider.md 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider')
+
+## OracleDistributedSynchronizationProvider(IDbConnection) Constructor
+
+Constructs a provider that connects with [connection](OracleDistributedSynchronizationProvider..ctor.piz12qaqFtocRjH6VWNIGQ.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(System.Data.IDbConnection).connection 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(System.Data.IDbConnection).connection').
+
+```csharp
+public OracleDistributedSynchronizationProvider(System.Data.IDbConnection connection);
+```
+#### Parameters
+
+
+
+`connection` [System.Data.IDbConnection](https://docs.microsoft.com/en-us/dotnet/api/System.Data.IDbConnection 'System.Data.IDbConnection')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider.CreateLock.7wcJ5e/hOrfQ/3Ylf2MDrw.md b/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider.CreateLock.7wcJ5e/hOrfQ/3Ylf2MDrw.md
new file mode 100644
index 00000000..b9b02064
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider.CreateLock.7wcJ5e/hOrfQ/3Ylf2MDrw.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedSynchronizationProvider](OracleDistributedSynchronizationProvider.md 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider')
+
+## OracleDistributedSynchronizationProvider.CreateLock(string, bool) Method
+
+Creates a [OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock') with the provided [name](OracleDistributedSynchronizationProvider.CreateLock.7wcJ5e/hOrfQ/3Ylf2MDrw.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateLock(string,bool).name 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateLock(string, bool).name'). Unless [exactName](OracleDistributedSynchronizationProvider.CreateLock.7wcJ5e/hOrfQ/3Ylf2MDrw.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateLock(string,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateLock(string, bool).exactName')
+is specified, invalid names will be escaped/hashed.
+
+```csharp
+public Medallion.Threading.Oracle.OracleDistributedLock CreateLock(string name, bool exactName=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`exactName` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+#### Returns
+[OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider.CreateReaderWriterLock.c5P1XG9aduRCEZMRz2ynkQ.md b/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider.CreateReaderWriterLock.c5P1XG9aduRCEZMRz2ynkQ.md
new file mode 100644
index 00000000..b9657694
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider.CreateReaderWriterLock.c5P1XG9aduRCEZMRz2ynkQ.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle').[OracleDistributedSynchronizationProvider](OracleDistributedSynchronizationProvider.md 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider')
+
+## OracleDistributedSynchronizationProvider.CreateReaderWriterLock(string, bool) Method
+
+Creates a [OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock') with the provided [name](OracleDistributedSynchronizationProvider.CreateReaderWriterLock.c5P1XG9aduRCEZMRz2ynkQ.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateReaderWriterLock(string,bool).name 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateReaderWriterLock(string, bool).name'). Unless [exactName](OracleDistributedSynchronizationProvider.CreateReaderWriterLock.c5P1XG9aduRCEZMRz2ynkQ.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateReaderWriterLock(string,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateReaderWriterLock(string, bool).exactName')
+is specified, invalid names will be escaped/hashed.
+
+```csharp
+public Medallion.Threading.Oracle.OracleDistributedReaderWriterLock CreateReaderWriterLock(string name, bool exactName=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`exactName` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+#### Returns
+[OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider.md b/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider.md
new file mode 100644
index 00000000..29aa7068
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/OracleDistributedSynchronizationProvider.md
@@ -0,0 +1,28 @@
+#### [DistributedLock.Oracle](README.md 'README')
+### [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle')
+
+## OracleDistributedSynchronizationProvider Class
+
+Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') for [OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock')
+and [IDistributedUpgradeableReaderWriterLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider') for [OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock')
+
+```csharp
+public sealed class OracleDistributedSynchronizationProvider :
+Medallion.Threading.IDistributedLockProvider,
+Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider,
+Medallion.Threading.IDistributedReaderWriterLockProvider
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 OracleDistributedSynchronizationProvider
+
+Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider'), [IDistributedUpgradeableReaderWriterLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedUpgradeableReaderWriterLockProvider.md 'Medallion.Threading.IDistributedUpgradeableReaderWriterLockProvider'), [IDistributedReaderWriterLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider')
+
+| Constructors | |
+| :--- | :--- |
+| [OracleDistributedSynchronizationProvider(string, Action<OracleConnectionOptionsBuilder>)](OracleDistributedSynchronizationProvider..ctor.Vs3QzXeKG/WYsARra1TfMA.md 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(string, System.Action)') | Constructs a provider that connects with [connectionString](OracleDistributedSynchronizationProvider..ctor.Vs3QzXeKG/WYsARra1TfMA.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_).connectionString 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(string, System.Action).connectionString') and [options](OracleDistributedSynchronizationProvider..ctor.Vs3QzXeKG/WYsARra1TfMA.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(string,System.Action_Medallion.Threading.Oracle.OracleConnectionOptionsBuilder_).options 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(string, System.Action).options'). |
+| [OracleDistributedSynchronizationProvider(IDbConnection)](OracleDistributedSynchronizationProvider..ctor.piz12qaqFtocRjH6VWNIGQ.md 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(System.Data.IDbConnection)') | Constructs a provider that connects with [connection](OracleDistributedSynchronizationProvider..ctor.piz12qaqFtocRjH6VWNIGQ.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(System.Data.IDbConnection).connection 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.OracleDistributedSynchronizationProvider(System.Data.IDbConnection).connection'). |
+
+| Methods | |
+| :--- | :--- |
+| [CreateLock(string, bool)](OracleDistributedSynchronizationProvider.CreateLock.7wcJ5e/hOrfQ/3Ylf2MDrw.md 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateLock(string, bool)') | Creates a [OracleDistributedLock](OracleDistributedLock.md 'Medallion.Threading.Oracle.OracleDistributedLock') with the provided [name](OracleDistributedSynchronizationProvider.CreateLock.7wcJ5e/hOrfQ/3Ylf2MDrw.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateLock(string,bool).name 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateLock(string, bool).name'). Unless [exactName](OracleDistributedSynchronizationProvider.CreateLock.7wcJ5e/hOrfQ/3Ylf2MDrw.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateLock(string,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateLock(string, bool).exactName') is specified, invalid names will be escaped/hashed. |
+| [CreateReaderWriterLock(string, bool)](OracleDistributedSynchronizationProvider.CreateReaderWriterLock.c5P1XG9aduRCEZMRz2ynkQ.md 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateReaderWriterLock(string, bool)') | Creates a [OracleDistributedReaderWriterLock](OracleDistributedReaderWriterLock.md 'Medallion.Threading.Oracle.OracleDistributedReaderWriterLock') with the provided [name](OracleDistributedSynchronizationProvider.CreateReaderWriterLock.c5P1XG9aduRCEZMRz2ynkQ.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateReaderWriterLock(string,bool).name 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateReaderWriterLock(string, bool).name'). Unless [exactName](OracleDistributedSynchronizationProvider.CreateReaderWriterLock.c5P1XG9aduRCEZMRz2ynkQ.md#Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateReaderWriterLock(string,bool).exactName 'Medallion.Threading.Oracle.OracleDistributedSynchronizationProvider.CreateReaderWriterLock(string, bool).exactName') is specified, invalid names will be escaped/hashed. |
diff --git a/docs/api/DistributedLock.Oracle/README.md b/docs/api/DistributedLock.Oracle/README.md
new file mode 100644
index 00000000..7b3a511e
--- /dev/null
+++ b/docs/api/DistributedLock.Oracle/README.md
@@ -0,0 +1,7 @@
+#### [DistributedLock.Oracle](README.md 'README')
+
+## DistributedLock.Oracle Assembly
+
+| Namespaces | |
+| :--- | :--- |
+| [Medallion.Threading.Oracle](Medallion.Threading.Oracle.md 'Medallion.Threading.Oracle') | |
diff --git a/docs/api/DistributedLock.Postgres/Medallion.Threading.Postgres.md b/docs/api/DistributedLock.Postgres/Medallion.Threading.Postgres.md
new file mode 100644
index 00000000..e0936c57
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/Medallion.Threading.Postgres.md
@@ -0,0 +1,16 @@
+#### [DistributedLock.Postgres](README.md 'README')
+
+## Medallion.Threading.Postgres Namespace
+
+| Classes | |
+| :--- | :--- |
+| [PostgresConnectionOptionsBuilder](PostgresConnectionOptionsBuilder.md 'Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder') | Specifies options for connecting to and locking against a Postgres database |
+| [PostgresDistributedLock](PostgresDistributedLock.md 'Medallion.Threading.Postgres.PostgresDistributedLock') | Implements a distributed lock using Postgres advisory locks (see https://www.postgresql.org/docs/12/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS) |
+| [PostgresDistributedLockHandle](PostgresDistributedLockHandle.md 'Medallion.Threading.Postgres.PostgresDistributedLockHandle') | Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') |
+| [PostgresDistributedReaderWriterLock](PostgresDistributedReaderWriterLock.md 'Medallion.Threading.Postgres.PostgresDistributedReaderWriterLock') | Implements a distributed lock using Postgres advisory locks (see https://www.postgresql.org/docs/12/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS) |
+| [PostgresDistributedReaderWriterLockHandle](PostgresDistributedReaderWriterLockHandle.md 'Medallion.Threading.Postgres.PostgresDistributedReaderWriterLockHandle') | Implements [IDistributedSynchronizationHandle](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedSynchronizationHandle.md 'Medallion.Threading.IDistributedSynchronizationHandle') |
+| [PostgresDistributedSynchronizationProvider](PostgresDistributedSynchronizationProvider.md 'Medallion.Threading.Postgres.PostgresDistributedSynchronizationProvider') | Implements [IDistributedLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLockProvider.md 'Medallion.Threading.IDistributedLockProvider') for [PostgresDistributedLock](PostgresDistributedLock.md 'Medallion.Threading.Postgres.PostgresDistributedLock') and [IDistributedReaderWriterLockProvider](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedReaderWriterLockProvider.md 'Medallion.Threading.IDistributedReaderWriterLockProvider') for [PostgresDistributedReaderWriterLock](PostgresDistributedReaderWriterLock.md 'Medallion.Threading.Postgres.PostgresDistributedReaderWriterLock'). |
+
+| Structs | |
+| :--- | :--- |
+| [PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey') | Acts as the "name" of a distributed lock in Postgres. Consists of one 64-bit value or two 32-bit values (the spaces do not overlap). See https://www.postgresql.org/docs/12/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS |
diff --git a/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey..ctor.LedpDNSMoNGTkn636aYbow.md b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey..ctor.LedpDNSMoNGTkn636aYbow.md
new file mode 100644
index 00000000..df038d42
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey..ctor.LedpDNSMoNGTkn636aYbow.md
@@ -0,0 +1,20 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+## PostgresAdvisoryLockKey(int, int) Constructor
+
+Constructs a key from a pair of 32-bit values. This is a separate key space
+than [PostgresAdvisoryLockKey(long)](PostgresAdvisoryLockKey..ctor.zWR+TwIbSGzvQzL9/uWeBQ.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(long)').
+
+```csharp
+public PostgresAdvisoryLockKey(int key1, int key2);
+```
+#### Parameters
+
+
+
+`key1` [System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
+
+
+
+`key2` [System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey..ctor.nrSDuGGKUsKtcB73EU1nXg.md b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey..ctor.nrSDuGGKUsKtcB73EU1nXg.md
new file mode 100644
index 00000000..392d6ea6
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey..ctor.nrSDuGGKUsKtcB73EU1nXg.md
@@ -0,0 +1,27 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+## PostgresAdvisoryLockKey(string, bool) Constructor
+
+Constructs a key based on a string [name](PostgresAdvisoryLockKey..ctor.nrSDuGGKUsKtcB73EU1nXg.md#Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string,bool).name 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string, bool).name').
+
+If the string is of the form "{16-digit hex}" or "{8-digit hex},{8-digit hex}", this will be parsed into numeric keys.
+
+If the string is an ascii string with 9 or fewer characters, it will be mapped to a key that does not collide with
+any other key based on such a string or based on a 32-bit value.
+
+Other string names will be rejected unless [allowHashing](PostgresAdvisoryLockKey..ctor.nrSDuGGKUsKtcB73EU1nXg.md#Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string,bool).allowHashing 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string, bool).allowHashing') is specified, in which case it will be hashed to
+a 64-bit key value.
+
+```csharp
+public PostgresAdvisoryLockKey(string name, bool allowHashing=false);
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`allowHashing` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey..ctor.zWR+TwIbSGzvQzL9/uWeBQ.md b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey..ctor.zWR+TwIbSGzvQzL9/uWeBQ.md
new file mode 100644
index 00000000..d6a108a9
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey..ctor.zWR+TwIbSGzvQzL9/uWeBQ.md
@@ -0,0 +1,16 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+## PostgresAdvisoryLockKey(long) Constructor
+
+Constructs a key from a single 64-bit value. This is a separate key space
+than [PostgresAdvisoryLockKey(int, int)](PostgresAdvisoryLockKey..ctor.LedpDNSMoNGTkn636aYbow.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(int, int)').
+
+```csharp
+public PostgresAdvisoryLockKey(long key);
+```
+#### Parameters
+
+
+
+`key` [System.Int64](https://docs.microsoft.com/en-us/dotnet/api/System.Int64 'System.Int64')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.Equals.+QU35/RcjHTGcjW0iCLCkA.md b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.Equals.+QU35/RcjHTGcjW0iCLCkA.md
new file mode 100644
index 00000000..e8cc570c
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.Equals.+QU35/RcjHTGcjW0iCLCkA.md
@@ -0,0 +1,18 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+## PostgresAdvisoryLockKey.Equals(PostgresAdvisoryLockKey) Method
+
+Implements [System.IEquatable<>.Equals(@0)](https://docs.microsoft.com/en-us/dotnet/api/System.IEquatable-1.Equals#System_IEquatable_1_Equals__0_ 'System.IEquatable`1.Equals(`0)')
+
+```csharp
+public bool Equals(Medallion.Threading.Postgres.PostgresAdvisoryLockKey that);
+```
+#### Parameters
+
+
+
+`that` [PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+#### Returns
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.Equals.hCSLKXsGZ9vchAeOS3hn/Q.md b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.Equals.hCSLKXsGZ9vchAeOS3hn/Q.md
new file mode 100644
index 00000000..0fead8d4
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.Equals.hCSLKXsGZ9vchAeOS3hn/Q.md
@@ -0,0 +1,18 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+## PostgresAdvisoryLockKey.Equals(object) Method
+
+Implements [System.Object.Equals(System.Object)](https://docs.microsoft.com/en-us/dotnet/api/System.Object.Equals#System_Object_Equals_System_Object_ 'System.Object.Equals(System.Object)')
+
+```csharp
+public override bool Equals(object obj);
+```
+#### Parameters
+
+
+
+`obj` [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object')
+
+#### Returns
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.GetHashCode().md b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.GetHashCode().md
new file mode 100644
index 00000000..0b62ccdc
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.GetHashCode().md
@@ -0,0 +1,13 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+## PostgresAdvisoryLockKey.GetHashCode() Method
+
+Implements [System.Object.GetHashCode](https://docs.microsoft.com/en-us/dotnet/api/System.Object.GetHashCode 'System.Object.GetHashCode')
+
+```csharp
+public override int GetHashCode();
+```
+
+#### Returns
+[System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.ToString().md b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.ToString().md
new file mode 100644
index 00000000..f3dd31a9
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.ToString().md
@@ -0,0 +1,14 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+## PostgresAdvisoryLockKey.ToString() Method
+
+Returns a string representation of the key that can be round-tripped through
+[PostgresAdvisoryLockKey(string, bool)](PostgresAdvisoryLockKey..ctor.nrSDuGGKUsKtcB73EU1nXg.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string, bool)')
+
+```csharp
+public override string ToString();
+```
+
+#### Returns
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.md b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.md
new file mode 100644
index 00000000..97288e91
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.md
@@ -0,0 +1,32 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres')
+
+## PostgresAdvisoryLockKey Struct
+
+Acts as the "name" of a distributed lock in Postgres. Consists of one 64-bit value or two 32-bit values (the spaces do not overlap).
+See https://www.postgresql.org/docs/12/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
+
+```csharp
+public readonly struct PostgresAdvisoryLockKey :
+System.IEquatable
+```
+
+Implements [System.IEquatable<](https://docs.microsoft.com/en-us/dotnet/api/System.IEquatable-1 'System.IEquatable`1')[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')[>](https://docs.microsoft.com/en-us/dotnet/api/System.IEquatable-1 'System.IEquatable`1')
+
+| Constructors | |
+| :--- | :--- |
+| [PostgresAdvisoryLockKey(int, int)](PostgresAdvisoryLockKey..ctor.LedpDNSMoNGTkn636aYbow.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(int, int)') | Constructs a key from a pair of 32-bit values. This is a separate key space than [PostgresAdvisoryLockKey(long)](PostgresAdvisoryLockKey..ctor.zWR+TwIbSGzvQzL9/uWeBQ.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(long)'). |
+| [PostgresAdvisoryLockKey(long)](PostgresAdvisoryLockKey..ctor.zWR+TwIbSGzvQzL9/uWeBQ.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(long)') | Constructs a key from a single 64-bit value. This is a separate key space than [PostgresAdvisoryLockKey(int, int)](PostgresAdvisoryLockKey..ctor.LedpDNSMoNGTkn636aYbow.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(int, int)'). |
+| [PostgresAdvisoryLockKey(string, bool)](PostgresAdvisoryLockKey..ctor.nrSDuGGKUsKtcB73EU1nXg.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string, bool)') | Constructs a key based on a string [name](PostgresAdvisoryLockKey..ctor.nrSDuGGKUsKtcB73EU1nXg.md#Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string,bool).name 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string, bool).name'). If the string is of the form "{16-digit hex}" or "{8-digit hex},{8-digit hex}", this will be parsed into numeric keys. If the string is an ascii string with 9 or fewer characters, it will be mapped to a key that does not collide with any other key based on such a string or based on a 32-bit value. Other string names will be rejected unless [allowHashing](PostgresAdvisoryLockKey..ctor.nrSDuGGKUsKtcB73EU1nXg.md#Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string,bool).allowHashing 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string, bool).allowHashing') is specified, in which case it will be hashed to a 64-bit key value. |
+
+| Methods | |
+| :--- | :--- |
+| [Equals(PostgresAdvisoryLockKey)](PostgresAdvisoryLockKey.Equals.+QU35/RcjHTGcjW0iCLCkA.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.Equals(Medallion.Threading.Postgres.PostgresAdvisoryLockKey)') | Implements [System.IEquatable<>.Equals(@0)](https://docs.microsoft.com/en-us/dotnet/api/System.IEquatable-1.Equals#System_IEquatable_1_Equals__0_ 'System.IEquatable`1.Equals(`0)') |
+| [Equals(object)](PostgresAdvisoryLockKey.Equals.hCSLKXsGZ9vchAeOS3hn/Q.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.Equals(object)') | Implements [System.Object.Equals(System.Object)](https://docs.microsoft.com/en-us/dotnet/api/System.Object.Equals#System_Object_Equals_System_Object_ 'System.Object.Equals(System.Object)') |
+| [GetHashCode()](PostgresAdvisoryLockKey.GetHashCode().md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.GetHashCode()') | Implements [System.Object.GetHashCode](https://docs.microsoft.com/en-us/dotnet/api/System.Object.GetHashCode 'System.Object.GetHashCode') |
+| [ToString()](PostgresAdvisoryLockKey.ToString().md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.ToString()') | Returns a string representation of the key that can be round-tripped through [PostgresAdvisoryLockKey(string, bool)](PostgresAdvisoryLockKey..ctor.nrSDuGGKUsKtcB73EU1nXg.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(string, bool)') |
+
+| Operators | |
+| :--- | :--- |
+| [operator ==(PostgresAdvisoryLockKey, PostgresAdvisoryLockKey)](PostgresAdvisoryLockKey.op_Equality.WzLfN5crVgBoMiN0RMIAhA.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.op_Equality(Medallion.Threading.Postgres.PostgresAdvisoryLockKey, Medallion.Threading.Postgres.PostgresAdvisoryLockKey)') | Provides equality based on [Equals(PostgresAdvisoryLockKey)](PostgresAdvisoryLockKey.Equals.+QU35/RcjHTGcjW0iCLCkA.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.Equals(Medallion.Threading.Postgres.PostgresAdvisoryLockKey)') |
+| [operator !=(PostgresAdvisoryLockKey, PostgresAdvisoryLockKey)](PostgresAdvisoryLockKey.op_Inequality.QLx2INIQzAIzn1yA2+FG0Q.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.op_Inequality(Medallion.Threading.Postgres.PostgresAdvisoryLockKey, Medallion.Threading.Postgres.PostgresAdvisoryLockKey)') | Provides inequality based on [Equals(PostgresAdvisoryLockKey)](PostgresAdvisoryLockKey.Equals.+QU35/RcjHTGcjW0iCLCkA.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.Equals(Medallion.Threading.Postgres.PostgresAdvisoryLockKey)') |
diff --git a/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.op_Equality.WzLfN5crVgBoMiN0RMIAhA.md b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.op_Equality.WzLfN5crVgBoMiN0RMIAhA.md
new file mode 100644
index 00000000..5ce42caf
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.op_Equality.WzLfN5crVgBoMiN0RMIAhA.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+## PostgresAdvisoryLockKey.operator ==(PostgresAdvisoryLockKey, PostgresAdvisoryLockKey) Operator
+
+Provides equality based on [Equals(PostgresAdvisoryLockKey)](PostgresAdvisoryLockKey.Equals.+QU35/RcjHTGcjW0iCLCkA.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.Equals(Medallion.Threading.Postgres.PostgresAdvisoryLockKey)')
+
+```csharp
+public static bool operator ==(Medallion.Threading.Postgres.PostgresAdvisoryLockKey a, Medallion.Threading.Postgres.PostgresAdvisoryLockKey b);
+```
+#### Parameters
+
+
+
+`a` [PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+
+
+`b` [PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+#### Returns
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.op_Inequality.QLx2INIQzAIzn1yA2+FG0Q.md b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.op_Inequality.QLx2INIQzAIzn1yA2+FG0Q.md
new file mode 100644
index 00000000..7328789d
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresAdvisoryLockKey.op_Inequality.QLx2INIQzAIzn1yA2+FG0Q.md
@@ -0,0 +1,22 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+## PostgresAdvisoryLockKey.operator !=(PostgresAdvisoryLockKey, PostgresAdvisoryLockKey) Operator
+
+Provides inequality based on [Equals(PostgresAdvisoryLockKey)](PostgresAdvisoryLockKey.Equals.+QU35/RcjHTGcjW0iCLCkA.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey.Equals(Medallion.Threading.Postgres.PostgresAdvisoryLockKey)')
+
+```csharp
+public static bool operator !=(Medallion.Threading.Postgres.PostgresAdvisoryLockKey a, Medallion.Threading.Postgres.PostgresAdvisoryLockKey b);
+```
+#### Parameters
+
+
+
+`a` [PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+
+
+`b` [PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+#### Returns
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.KeepaliveCadence.3nQNyNVWx1MTQ4W8SFqI9w.md b/docs/api/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.KeepaliveCadence.3nQNyNVWx1MTQ4W8SFqI9w.md
new file mode 100644
index 00000000..5f1f8e4a
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.KeepaliveCadence.3nQNyNVWx1MTQ4W8SFqI9w.md
@@ -0,0 +1,23 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresConnectionOptionsBuilder](PostgresConnectionOptionsBuilder.md 'Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder')
+
+## PostgresConnectionOptionsBuilder.KeepaliveCadence(TimeSpan) Method
+
+Some Postgres setups have automation in place which aggressively kills idle connections.
+
+To prevent this, this option sets the cadence at which we run a no-op "keepalive" query on a connection that is holding a lock.
+Note that this still does not guarantee protection for the connection from all conditions where the governor might kill it.
+
+Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan'), which disables keepalive.
+
+```csharp
+public Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder KeepaliveCadence(System.TimeSpan keepaliveCadence);
+```
+#### Parameters
+
+
+
+`keepaliveCadence` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+#### Returns
+[PostgresConnectionOptionsBuilder](PostgresConnectionOptionsBuilder.md 'Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.UseMultiplexing.iaWbIbzQ+9I/FdhQ+S89ng.md b/docs/api/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.UseMultiplexing.iaWbIbzQ+9I/FdhQ+S89ng.md
new file mode 100644
index 00000000..56e7b1fb
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.UseMultiplexing.iaWbIbzQ+9I/FdhQ+S89ng.md
@@ -0,0 +1,31 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresConnectionOptionsBuilder](PostgresConnectionOptionsBuilder.md 'Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder')
+
+## PostgresConnectionOptionsBuilder.UseMultiplexing(bool) Method
+
+This mode takes advantage of the fact that while "holding" a lock (or other synchronization primitive)
+a connection is essentially idle. Thus, rather than creating a new connection for each held lock it is
+often possible to multiplex a shared connection so that that connection can hold multiple locks at the same time.
+
+Multiplexing is on by default.
+
+This is implemented in such a way that releasing a lock held on such a connection will never be blocked by an
+Acquire() call that is waiting to acquire a lock on that same connection. For this reason, the multiplexing
+strategy is "optimistic": if the lock can't be acquired instantaneously on the shared connection, a new (shareable)
+connection will be allocated.
+
+This option can improve performance and avoid connection pool starvation in high-load scenarios. It is also
+particularly applicable to cases where [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)')
+semantics are used with a zero-length timeout.
+
+```csharp
+public Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder UseMultiplexing(bool useMultiplexing=true);
+```
+#### Parameters
+
+
+
+`useMultiplexing` [System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+#### Returns
+[PostgresConnectionOptionsBuilder](PostgresConnectionOptionsBuilder.md 'Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.md b/docs/api/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.md
new file mode 100644
index 00000000..b1e397e9
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.md
@@ -0,0 +1,17 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres')
+
+## PostgresConnectionOptionsBuilder Class
+
+Specifies options for connecting to and locking against a Postgres database
+
+```csharp
+public sealed class PostgresConnectionOptionsBuilder
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 PostgresConnectionOptionsBuilder
+
+| Methods | |
+| :--- | :--- |
+| [KeepaliveCadence(TimeSpan)](PostgresConnectionOptionsBuilder.KeepaliveCadence.3nQNyNVWx1MTQ4W8SFqI9w.md 'Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder.KeepaliveCadence(System.TimeSpan)') | Some Postgres setups have automation in place which aggressively kills idle connections. To prevent this, this option sets the cadence at which we run a no-op "keepalive" query on a connection that is holding a lock. Note that this still does not guarantee protection for the connection from all conditions where the governor might kill it. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan'), which disables keepalive. |
+| [UseMultiplexing(bool)](PostgresConnectionOptionsBuilder.UseMultiplexing.iaWbIbzQ+9I/FdhQ+S89ng.md 'Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder.UseMultiplexing(bool)') | This mode takes advantage of the fact that while "holding" a lock (or other synchronization primitive) a connection is essentially idle. Thus, rather than creating a new connection for each held lock it is often possible to multiplex a shared connection so that that connection can hold multiple locks at the same time. Multiplexing is on by default. This is implemented in such a way that releasing a lock held on such a connection will never be blocked by an Acquire() call that is waiting to acquire a lock on that same connection. For this reason, the multiplexing strategy is "optimistic": if the lock can't be acquired instantaneously on the shared connection, a new (shareable) connection will be allocated. This option can improve performance and avoid connection pool starvation in high-load scenarios. It is also particularly applicable to cases where [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)') semantics are used with a zero-length timeout. |
diff --git a/docs/api/DistributedLock.Postgres/PostgresDistributedLock..ctor.WrNsj1JRkAGtaHLdHnRFrg.md b/docs/api/DistributedLock.Postgres/PostgresDistributedLock..ctor.WrNsj1JRkAGtaHLdHnRFrg.md
new file mode 100644
index 00000000..23b4973b
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresDistributedLock..ctor.WrNsj1JRkAGtaHLdHnRFrg.md
@@ -0,0 +1,19 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresDistributedLock](PostgresDistributedLock.md 'Medallion.Threading.Postgres.PostgresDistributedLock')
+
+## PostgresDistributedLock(PostgresAdvisoryLockKey, IDbConnection) Constructor
+
+Constructs a lock with the given [key](PostgresDistributedLock..ctor.WrNsj1JRkAGtaHLdHnRFrg.md#Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey,System.Data.IDbConnection).key 'Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey, System.Data.IDbConnection).key') (effectively the lock name) and [connection](PostgresDistributedLock..ctor.WrNsj1JRkAGtaHLdHnRFrg.md#Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey,System.Data.IDbConnection).connection 'Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey, System.Data.IDbConnection).connection').
+
+```csharp
+public PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey key, System.Data.IDbConnection connection);
+```
+#### Parameters
+
+
+
+`key` [PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+
+
+`connection` [System.Data.IDbConnection](https://docs.microsoft.com/en-us/dotnet/api/System.Data.IDbConnection 'System.Data.IDbConnection')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresDistributedLock..ctor.zD9lmiuiSMIu1mI+FfWXDQ.md b/docs/api/DistributedLock.Postgres/PostgresDistributedLock..ctor.zD9lmiuiSMIu1mI+FfWXDQ.md
new file mode 100644
index 00000000..ea8668a9
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresDistributedLock..ctor.zD9lmiuiSMIu1mI+FfWXDQ.md
@@ -0,0 +1,24 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresDistributedLock](PostgresDistributedLock.md 'Medallion.Threading.Postgres.PostgresDistributedLock')
+
+## PostgresDistributedLock(PostgresAdvisoryLockKey, string, Action) Constructor
+
+Constructs a lock with the given [key](PostgresDistributedLock..ctor.zD9lmiuiSMIu1mI+FfWXDQ.md#Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey,string,System.Action_Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder_).key 'Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey, string, System.Action).key') (effectively the lock name), [connectionString](PostgresDistributedLock..ctor.zD9lmiuiSMIu1mI+FfWXDQ.md#Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey,string,System.Action_Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder_).connectionString 'Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey, string, System.Action).connectionString'),
+and [options](PostgresDistributedLock..ctor.zD9lmiuiSMIu1mI+FfWXDQ.md#Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey,string,System.Action_Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder_).options 'Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey, string, System.Action).options')
+
+```csharp
+public PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey key, string connectionString, System.Action? options=null);
+```
+#### Parameters
+
+
+
+`key` [PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
+
+
+
+`connectionString` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+
+`options` [System.Action<](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')[PostgresConnectionOptionsBuilder](PostgresConnectionOptionsBuilder.md 'Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Action-1 'System.Action`1')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresDistributedLock.Acquire.wevmsPrIfDcimdIlhBziiw.md b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.Acquire.wevmsPrIfDcimdIlhBziiw.md
new file mode 100644
index 00000000..97677c40
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.Acquire.wevmsPrIfDcimdIlhBziiw.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresDistributedLock](PostgresDistributedLock.md 'Medallion.Threading.Postgres.PostgresDistributedLock')
+
+## PostgresDistributedLock.Acquire(Nullable, CancellationToken) Method
+
+Acquires the lock synchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+using (myLock.Acquire(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public Medallion.Threading.Postgres.PostgresDistributedLockHandle Acquire(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [Acquire(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.Acquire.Q+8FXimBZqUrDv5tTRw59w.md 'Medallion.Threading.IDistributedLock.Acquire(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[PostgresDistributedLockHandle](PostgresDistributedLockHandle.md 'Medallion.Threading.Postgres.PostgresDistributedLockHandle')
+A [PostgresDistributedLockHandle](PostgresDistributedLockHandle.md 'Medallion.Threading.Postgres.PostgresDistributedLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresDistributedLock.AcquireAsync.Vmz1wx/1suZB7AWMDkEWqA.md b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.AcquireAsync.Vmz1wx/1suZB7AWMDkEWqA.md
new file mode 100644
index 00000000..9f6d09cd
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.AcquireAsync.Vmz1wx/1suZB7AWMDkEWqA.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresDistributedLock](PostgresDistributedLock.md 'Medallion.Threading.Postgres.PostgresDistributedLock')
+
+## PostgresDistributedLock.AcquireAsync(Nullable, CancellationToken) Method
+
+Acquires the lock asynchronously, failing with [System.TimeoutException](https://docs.microsoft.com/en-us/dotnet/api/System.TimeoutException 'System.TimeoutException') if the attempt times out. Usage:
+
+```csharp
+await using (await myLock.AcquireAsync(...))
+{
+ /* we have the lock! */
+}
+// dispose releases the lock
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask AcquireAsync(System.Nullable timeout=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.Nullable<](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')[System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Nullable-1 'System.Nullable`1')
+
+How long to wait before giving up on the acquisition attempt. Defaults to [System.Threading.Timeout.InfiniteTimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Timeout.InfiniteTimeSpan 'System.Threading.Timeout.InfiniteTimeSpan')
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [AcquireAsync(Nullable<TimeSpan>, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.AcquireAsync.0Lol7Hv58Kl+UVYSOI6IpQ.md 'Medallion.Threading.IDistributedLock.AcquireAsync(System.Nullable{System.TimeSpan},System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[PostgresDistributedLockHandle](PostgresDistributedLockHandle.md 'Medallion.Threading.Postgres.PostgresDistributedLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+A [PostgresDistributedLockHandle](PostgresDistributedLockHandle.md 'Medallion.Threading.Postgres.PostgresDistributedLockHandle') which can be used to release the lock
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresDistributedLock.Key.md b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.Key.md
new file mode 100644
index 00000000..7f80fda6
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.Key.md
@@ -0,0 +1,13 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresDistributedLock](PostgresDistributedLock.md 'Medallion.Threading.Postgres.PostgresDistributedLock')
+
+## PostgresDistributedLock.Key Property
+
+The [PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey') that uniquely identifies the lock on the database
+
+```csharp
+public Medallion.Threading.Postgres.PostgresAdvisoryLockKey Key { get; }
+```
+
+#### Property Value
+[PostgresAdvisoryLockKey](PostgresAdvisoryLockKey.md 'Medallion.Threading.Postgres.PostgresAdvisoryLockKey')
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresDistributedLock.TryAcquire.m+KJTn2pfMV+kQiMfrpLuQ.md b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.TryAcquire.m+KJTn2pfMV+kQiMfrpLuQ.md
new file mode 100644
index 00000000..b60447be
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.TryAcquire.m+KJTn2pfMV+kQiMfrpLuQ.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresDistributedLock](PostgresDistributedLock.md 'Medallion.Threading.Postgres.PostgresDistributedLock')
+
+## PostgresDistributedLock.TryAcquire(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock synchronously. Usage:
+
+```csharp
+using (var handle = myLock.TryAcquire(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public Medallion.Threading.Postgres.PostgresDistributedLockHandle? TryAcquire(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquire(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquire.GcM73KNvUAY5aoOOhgln1g.md 'Medallion.Threading.IDistributedLock.TryAcquire(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[PostgresDistributedLockHandle](PostgresDistributedLockHandle.md 'Medallion.Threading.Postgres.PostgresDistributedLockHandle')
+A [PostgresDistributedLockHandle](PostgresDistributedLockHandle.md 'Medallion.Threading.Postgres.PostgresDistributedLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresDistributedLock.TryAcquireAsync.vpSo9yMiuK1NYo8xC2ACUw.md b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.TryAcquireAsync.vpSo9yMiuK1NYo8xC2ACUw.md
new file mode 100644
index 00000000..ec162b3f
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.TryAcquireAsync.vpSo9yMiuK1NYo8xC2ACUw.md
@@ -0,0 +1,37 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres').[PostgresDistributedLock](PostgresDistributedLock.md 'Medallion.Threading.Postgres.PostgresDistributedLock')
+
+## PostgresDistributedLock.TryAcquireAsync(TimeSpan, CancellationToken) Method
+
+Attempts to acquire the lock asynchronously. Usage:
+
+```csharp
+await using (var handle = await myLock.TryAcquireAsync(...))
+{
+ if (handle != null) { /* we have the lock! */ }
+}
+// dispose releases the lock if we took it
+```
+
+```csharp
+public System.Threading.Tasks.ValueTask TryAcquireAsync(System.TimeSpan timeout=default(System.TimeSpan), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
+```
+#### Parameters
+
+
+
+`timeout` [System.TimeSpan](https://docs.microsoft.com/en-us/dotnet/api/System.TimeSpan 'System.TimeSpan')
+
+How long to wait before giving up on the acquisition attempt. Defaults to 0
+
+
+
+`cancellationToken` [System.Threading.CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.CancellationToken 'System.Threading.CancellationToken')
+
+Specifies a token by which the wait can be canceled
+
+Implements [TryAcquireAsync(TimeSpan, CancellationToken)](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.TryAcquireAsync.ZLhweq3GadK5OwGmTwruEQ.md 'Medallion.Threading.IDistributedLock.TryAcquireAsync(System.TimeSpan,System.Threading.CancellationToken)')
+
+#### Returns
+[System.Threading.Tasks.ValueTask<](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')[PostgresDistributedLockHandle](PostgresDistributedLockHandle.md 'Medallion.Threading.Postgres.PostgresDistributedLockHandle')[>](https://docs.microsoft.com/en-us/dotnet/api/System.Threading.Tasks.ValueTask-1 'System.Threading.Tasks.ValueTask`1')
+A [PostgresDistributedLockHandle](PostgresDistributedLockHandle.md 'Medallion.Threading.Postgres.PostgresDistributedLockHandle') which can be used to release the lock or null on failure
\ No newline at end of file
diff --git a/docs/api/DistributedLock.Postgres/PostgresDistributedLock.md b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.md
new file mode 100644
index 00000000..1b6057bb
--- /dev/null
+++ b/docs/api/DistributedLock.Postgres/PostgresDistributedLock.md
@@ -0,0 +1,32 @@
+#### [DistributedLock.Postgres](README.md 'README')
+### [Medallion.Threading.Postgres](Medallion.Threading.Postgres.md 'Medallion.Threading.Postgres')
+
+## PostgresDistributedLock Class
+
+Implements a distributed lock using Postgres advisory locks
+(see https://www.postgresql.org/docs/12/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS)
+
+```csharp
+public sealed class PostgresDistributedLock :
+Medallion.Threading.IDistributedLock
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 PostgresDistributedLock
+
+Implements [IDistributedLock](https://github.com/madelson/DistributedLock/tree/default-documentation/docs/api/DistributedLock.Core/IDistributedLock.md 'Medallion.Threading.IDistributedLock')
+
+| Constructors | |
+| :--- | :--- |
+| [PostgresDistributedLock(PostgresAdvisoryLockKey, string, Action<PostgresConnectionOptionsBuilder>)](PostgresDistributedLock..ctor.zD9lmiuiSMIu1mI+FfWXDQ.md 'Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey, string, System.Action)') | Constructs a lock with the given [key](PostgresDistributedLock..ctor.zD9lmiuiSMIu1mI+FfWXDQ.md#Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey,string,System.Action_Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder_).key 'Medallion.Threading.Postgres.PostgresDistributedLock.PostgresDistributedLock(Medallion.Threading.Postgres.PostgresAdvisoryLockKey, string, System.Action