Generic Volatile.Read to Thread.VolatileRead conversion

49 Views Asked by At

I need to get this code from .NET 4.5+ working on .NET 4.0. The generic Volatile.Read isn't available in that version. I'm trying to use the Thread.VolatileRead to get this working. I need to know if this outright a bad idea and if not, what I should test for?

See what I replaced in the commented line.

internal static TValue EnsureSingletonInitialized<TValue, TArg>(ref TValue value,
    TArg arg, Func<TArg, TValue> initialize)
    where TValue : class
{
    //TValue currentValue = Volatile.Read(ref value);

    object o = value;
    TValue currentValue = (TValue)Thread.VolatileRead(ref o);

    if (null != currentValue)
        return currentValue;

    TValue candidateValue = initialize(arg);

    return Interlocked.CompareExchange(ref value, candidateValue, null) ?? candidateValue;
}
1

There are 1 best solutions below

2
Theodor Zoulias On BEST ANSWER

The safest implementations of the missing Read<T>/Write<T> methods are probably these:

public static class VolatileEx
{
    public static T Read<T>(ref T location) where T : class
    {
        return Interlocked.CompareExchange(ref location, null, null);
    }

    public static void Write<T>(ref T location, T value) where T : class
    {
        Interlocked.Exchange(ref location, value);
    }
}

Using the Interlocked ensures that the Read/Write are atomic, and also that the preceding/following instructions will not be reordered. The Interlocked APIs impose full memory barriers, so they are more expensive than the Volatile APIs that impose half fences. But since you downgraded to an older .NET platform, losing some performance is to be expected.

Source code: