Created
June 4, 2022 18:13
-
-
Save mrpmorris/1ec5b57189fe5c7541f3a58fb1b11141 to your computer and use it in GitHub Desktop.
SpinLock extension without a ref
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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