Skip to content

Instantly share code, notes, and snippets.

@NickStrupat
Last active August 4, 2024 07:07
Show Gist options
  • Save NickStrupat/6e5bfb2e8461a7f4da50ce6351bf0491 to your computer and use it in GitHub Desktop.
Save NickStrupat/6e5bfb2e8461a7f4da50ce6351bf0491 to your computer and use it in GitHub Desktop.
AsyncLock
using System;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// A simple FIFO async lock. It does not support recursion/reentrancy.
/// </summary>
public sealed class AsyncLock
{
private Task task = Task.CompletedTask;
public async ValueTask LockAsync(Func<Task> whenLocked)
{
ArgumentNullException.ThrowIfNull(whenLocked);
var next = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var prev = Interlocked.Exchange(ref task, next.Task);
await prev.ConfigureAwait(false);
try { await whenLocked().ConfigureAwait(false); }
finally { next.SetResult(); }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment