问题 C#volatile数组项?


我需要一个包含volatile项的数组,但是找不到这样做的方法。

private volatile T[] _arr;

这意味着_arr引用是易失性的,但它不保证_arr对象本身内的任何内容。

有没有办法将_arr的Items标记为volatile?

谢谢。

编辑:

以下代码根据二进制编码的答案构建。 这段代码是否可以使用线程安全?

public class VolatileArray<T>
{
    private T[] _arr;

    public VolatileArray(int length)
    {
        _arr = new T[length];
    }

    public VolatileArray(T[] arr)
    {
        _arr = arr;
    }

    public T this[int index]
    {
        get
        {
            T value = _arr[index];
            Thread.MemoryBarrier();
            return value;
        }

        set
        {
            Thread.MemoryBarrier();
            _arr[index] = value;
        }
    }

    public int Length
    {
        get { return _arr.Length; }
    }
}

8546
2017-12-05 16:47


起源

这个问题需要更多的爱。 - Repo Man


答案:


由于可以通过引用传递数组元素,因此可以使用 Thread.VolatileRead 和 Thread.VolatileWrite

理解它是有用的 volatile 关键字在幕后使用 Thread.MemoryBarrier。你可以写:

// Read
x = _arr[i];
Thread.MemoryBarrier();

// Write
Thread.MemoryBarrier();
_arr[i] = x;

注意 volatile 和 MemoryBarrier 是先进的技术,容易出错。例如,请参阅 我如何理解读取内存障碍和易失性。通常你会更好地使用更高级别的结构,例如 lockMonitorReaderWriterLockSlim, 和别的。


7
2017-12-05 17:05



IIRC,然后严格, volatile 关键字只需要适当的读或写屏障,而 Thread.MemoryBarrier() 有一个完整的障碍。因此,上述重量比同等用量略重 volatile 甚至在我们考虑它涉及方法调用之前。它仍然是我们能做的最好的(正如你所说,目前的实施 VolatileRead() 和 VolatileWrite())。 - Jon Hanna


使用 Volatile.Read(ref array[index]) 和 Volatile.Write(ref array[index], value)

Volatile 自.NET 4.5起可用。它允许从/向字段,数组元素读/写, ref 参数,指针。


2
2017-07-15 15:31





我认为你不能

你不能, volatile 被定义为场修改器(ECMA 334)。

而且我认为它也不会达到你想要的效果。
考虑:

 private T[] _arr;

 volatile T v;
 ....  v = _arr[x];
 ....  _arr[x] = v;

1
2017-12-05 16:54





我做了一个小结构,有助于保持清洁和OO

struct VolatileBoolean {
    public volatile Boolean Value;
}

VolatileBoolean[] arrayOfVolatileBooleans;
public void SomeMethod() {
    if (arrayOfVolatileBooleans[4].Value)
        DoSomething();
}

1
2018-03-22 15:29