Skip to content

Instantly share code, notes, and snippets.

@mrpmorris
Created June 4, 2022 18:13
Show Gist options
  • Save mrpmorris/1ec5b57189fe5c7541f3a58fb1b11141 to your computer and use it in GitHub Desktop.
Save mrpmorris/1ec5b57189fe5c7541f3a58fb1b11141 to your computer and use it in GitHub Desktop.
SpinLock extension without a ref
With `ref` in `this ref SpinLock source`
Got lock
Ready
Doing work
Releasing lock
Got lock
Doing work
Releasing lock
Got lock
Doing work
Releasing lock
Without `ref` in `this SpinLock source`
Ready
Got lock
Got lock
Got lock
Doing work
Doing work
Doing work
Releasing lock
Releasing lock
Releasing lock
using ConsoleApp11;
var sl = new SpinLock();
for (int i = 0; i < 3; i++)
{
_ = Task.Run(() => DoSomething(ref sl));
}
Console.WriteLine("Ready");
Console.ReadLine();
void DoSomething(ref SpinLock sl)
{
sl.ExecuteLocked(_ =>
{
Console.WriteLine("Doing work");
Thread.Sleep(1000);
});
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp11;
public static class SpinLockExtensions
{
public static void ExecuteLocked(
this ref SpinLock source,
Action<CancellationToken> task,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(source);
ArgumentNullException.ThrowIfNull(task);
bool hasLock = false;
do
{
source.Enter(ref hasLock);
}
while (!hasLock && !cancellationToken.IsCancellationRequested);
try
{
if (cancellationToken.IsCancellationRequested)
return;
Console.WriteLine("Got lock");
task(cancellationToken);
}
finally
{
if (hasLock)
{
Console.WriteLine("Releasing lock");
source.Exit();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment