DotNext by .NET Foundation and Contributors

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

 AtomicReference

public static class AtomicReference
Provides atomic operations for the reference type.
using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Threading; namespace DotNext.Threading { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public static class AtomicReference { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CompareAndSet<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, T expected, T update) where T : class { return Interlocked.CompareExchange(ref value, update, expected) == expected; } [MethodImpl(MethodImplOptions.AggressiveOptimization)] [System.Runtime.CompilerServices.NullableContext(0)] [return: System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] private static (T OldValue, T NewValue) Update<[System.Runtime.CompilerServices.Nullable(2)] T, TUpdater>([System.Runtime.CompilerServices.Nullable(1)] ref T value, TUpdater updater) where T : class where TUpdater : struct, ISupplier<T, T> { T val2; T val; do { val2 = ((ISupplier<T, T>)updater).Invoke(val = Volatile.Read(ref value)); } while (!CompareAndSet(ref value, val, val2)); return (val, val2); } [MethodImpl(MethodImplOptions.AggressiveOptimization)] [return: System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] private static (T OldValue, T NewValue) Accumulate<[System.Runtime.CompilerServices.Nullable(2)] T, [System.Runtime.CompilerServices.Nullable(0)] TAccumulator>(ref T value, T x, [System.Runtime.CompilerServices.Nullable(0)] TAccumulator accumulator) where T : class where TAccumulator : struct, ISupplier<T, T, T> { T val2; T val; do { val2 = ((ISupplier<T, T, T>)accumulator).Invoke(val = Volatile.Read(ref value), x); } while (!CompareAndSet(ref value, val, val2)); return (val, val2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T AccumulateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, T x, Func<T, T, T> accumulator) where T : class { return Accumulate(ref value, x, (DelegatingSupplier<T, T, T>)accumulator).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static T AccumulateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, T x, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1, 1 })] IntPtr accumulator) where T : class { return Accumulate(ref value, x, (Supplier<T, T, T>)(long)accumulator).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NotNullIfNotNull("value")] public static T GetAndAccumulate<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, T x, Func<T, T, T> accumulator) where T : class { return Accumulate(ref value, x, (DelegatingSupplier<T, T, T>)accumulator).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] [return: NotNullIfNotNull("value")] public static T GetAndAccumulate<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, T x, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1, 1 })] IntPtr accumulator) where T : class { return Accumulate(ref value, x, (Supplier<T, T, T>)(long)accumulator).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T UpdateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, Func<T, T> updater) where T : class { return Update(ref value, (DelegatingSupplier<T, T>)updater).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static T UpdateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] IntPtr updater) where T : class { return Update(ref value, (Supplier<T, T>)(long)updater).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NotNullIfNotNull("value")] public static T GetAndUpdate<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, Func<T, T> updater) where T : class { return Update(ref value, (DelegatingSupplier<T, T>)updater).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] [return: NotNullIfNotNull("value")] public static T GetAndUpdate<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] IntPtr updater) where T : class { return Update(ref value, (Supplier<T, T>)(long)updater).OldValue; } } }