Created
June 22, 2019 12:20
-
-
Save eiriktsarpalis/d877390a38aefe973524a6cf4e1d64b7 to your computer and use it in GitHub Desktop.
Clojure-style atoms for C#
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.Threading; | |
using System.Threading.Tasks; | |
namespace Atom | |
{ | |
public class Atom<T> where T : class | |
{ | |
private T _value; | |
public Atom(T value) | |
{ | |
_value = value; | |
} | |
public T Value => _value; | |
public void Swap(Func<T, T> updater) | |
{ | |
var sw = new SpinWait(); | |
while(true) | |
{ | |
var curr = _value; | |
var next = updater(curr); | |
var result = Interlocked.CompareExchange(ref _value, next, curr); | |
if (object.ReferenceEquals(result, curr)) | |
break; | |
sw.SpinOnce(); | |
} | |
} | |
} | |
public class AtomTests | |
{ | |
public static void Main(String[] args) | |
{ | |
var atom = new Atom<string>(""); | |
Parallel.For(0, 100, _ => atom.Swap(x => "x" + x)); | |
Console.WriteLine($"{atom.Value} {atom.Value.Length}"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment