I\'m trying to use Interlocked.CompareExchange with this enum:
public enum State {
Idle,
Running,
//...
}
The following code do
System.Runtime.CompilerServices.UnsafeHere's a pretty good related answer going into depth.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
public static class InterlockedEx
{
///
/// Enum equivalent of and
///
public static TEnum CompareExchange(ref TEnum location, TEnum value, TEnum comparand)
where TEnum : struct, Enum
{
return Unsafe.SizeOf() switch
{
// .NET does not support 1- and 2-byte atomic operations as there
// is no common hardware support for that.
4 => CompareExchange32Bit(ref location, value, comparand),
8 => CompareExchange64Bit(ref location, value, comparand),
_ => throw new NotSupportedException("Only enums with an underlying type of 4 bytes or 8 bytes are allowed to be used with Interlocked")
};
static TEnum CompareExchange32Bit(ref TEnum location, TEnum value, TEnum comparand)
{
int comparandRaw = Unsafe.As(ref comparand);
int valueRaw = Unsafe.As(ref value);
ref int locationRaw = ref Unsafe.As(ref location);
int returnRaw = Interlocked.CompareExchange(ref locationRaw, valueRaw, comparandRaw);
return Unsafe.As(ref returnRaw);
}
static TEnum CompareExchange64Bit(ref TEnum location, TEnum value, TEnum comparand)
{
long comparandRaw = Unsafe.As(ref comparand);
long valueRaw = Unsafe.As(ref value);
ref long locationRaw = ref Unsafe.As(ref location);
long returnRaw = Interlocked.CompareExchange(ref locationRaw, valueRaw, comparandRaw);
return Unsafe.As(ref returnRaw);
}
}
}