DotNext by Roman Sakno

<PackageReference Include="DotNext" Version="1.2.6" />

 AtomicReference

public static class AtomicReference
Provides atomic operations for the reference type.
using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; namespace DotNext.Threading { public static class AtomicReference { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CompareAndSet<T>(ref T value, T expected, T update) where T : class { return Interlocked.CompareExchange(ref value, update, expected) == expected; } private static (T OldValue, T NewValue) Update<T>(ref T value, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, T> updater) where T : class { T val2; T val; do { val2 = updater.Invoke(val = Volatile.Read(ref value)); } while (!CompareAndSet(ref value, val, val2)); return (val, val2); } private static (T OldValue, T NewValue) Accumulate<T>(ref T value, T x, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, T, T> accumulator) where T : class { T val2; T val; do { val2 = accumulator.Invoke(val = Volatile.Read(ref value), x); } while (!CompareAndSet(ref value, val, val2)); return (val, val2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T AccumulateAndGet<T>(ref T value, T x, Func<T, T, T> accumulator) where T : class { ValueFunc<T, T, T> accumulator2 = new ValueFunc<T, T, T>(accumulator, true); return AccumulateAndGet(ref value, x, ref accumulator2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T AccumulateAndGet<T>(ref T value, T x, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, T, T> accumulator) where T : class { return Accumulate(ref value, x, ref accumulator).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T GetAndAccumulate<T>(ref T value, T x, Func<T, T, T> accumulator) where T : class { ValueFunc<T, T, T> accumulator2 = new ValueFunc<T, T, T>(accumulator, true); return GetAndAccumulate(ref value, x, ref accumulator2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T GetAndAccumulate<T>(ref T value, T x, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, T, T> accumulator) where T : class { return Accumulate(ref value, x, ref accumulator).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T UpdateAndGet<T>(ref T value, Func<T, T> updater) where T : class { ValueFunc<T, T> updater2 = new ValueFunc<T, T>(updater, true); return UpdateAndGet(ref value, ref updater2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T UpdateAndGet<T>(ref T value, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, T> updater) where T : class { return Update(ref value, ref updater).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T GetAndUpdate<T>(ref T value, Func<T, T> updater) where T : class { ValueFunc<T, T> updater2 = new ValueFunc<T, T>(updater, true); return GetAndUpdate(ref value, ref updater2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T GetAndUpdate<T>(ref T value, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, T> updater) where T : class { return Update(ref value, ref updater).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T VolatileRead<T>(this T[] array, long index) where T : class { return Volatile.Read(ref array[index]); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void VolatileWrite<T>(this T[] array, long index, T element) where T : class { Volatile.Write(ref array[index], element); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CompareAndSet<T>(this T[] array, long index, T expected, T update) where T : class { return CompareAndSet(ref array[index], expected, update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T CompareExchange<T>(this T[] array, long index, T update, T comparand) where T : class { return Interlocked.CompareExchange(ref array[index], update, comparand); } public static T GetAndSet<T>(this T[] array, long index, T update) where T : class { return Interlocked.Exchange(ref array[index], update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T SetAndGet<T>(this T[] array, long index, T update) where T : class { array.VolatileWrite(index, update); return update; } public static T AccumulateAndGet<T>(this T[] array, long index, T x, Func<T, T, T> accumulator) where T : class { ValueFunc<T, T, T> accumulator2 = new ValueFunc<T, T, T>(accumulator, true); return array.AccumulateAndGet(index, x, ref accumulator2); } public static T AccumulateAndGet<T>(this T[] array, long index, T x, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, T, T> accumulator) where T : class { return AccumulateAndGet(ref array[index], x, ref accumulator); } public static T GetAndAccumulate<T>(this T[] array, long index, T x, Func<T, T, T> accumulator) where T : class { ValueFunc<T, T, T> accumulator2 = new ValueFunc<T, T, T>(accumulator, true); return array.GetAndAccumulate(index, x, ref accumulator2); } public static T GetAndAccumulate<T>(this T[] array, long index, T x, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, T, T> accumulator) where T : class { return GetAndAccumulate(ref array[index], x, ref accumulator); } public static T UpdateAndGet<T>(this T[] array, long index, Func<T, T> updater) where T : class { ValueFunc<T, T> updater2 = new ValueFunc<T, T>(updater, true); return array.UpdateAndGet(index, ref updater2); } public static T UpdateAndGet<T>(this T[] array, long index, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, T> updater) where T : class { return UpdateAndGet(ref array[index], ref updater); } public static T GetAndUpdate<T>(this T[] array, long index, Func<T, T> updater) where T : class { ValueFunc<T, T> updater2 = new ValueFunc<T, T>(updater, true); return array.GetAndUpdate(index, ref updater2); } public static T GetAndUpdate<T>(this T[] array, long index, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, T> updater) where T : class { return GetAndUpdate(ref array[index], ref updater); } } }