Skip to content

Instantly share code, notes, and snippets.

@eiriktsarpalis
Created June 22, 2019 12:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eiriktsarpalis/d877390a38aefe973524a6cf4e1d64b7 to your computer and use it in GitHub Desktop.
Save eiriktsarpalis/d877390a38aefe973524a6cf4e1d64b7 to your computer and use it in GitHub Desktop.
Clojure-style atoms for C#
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