17

我需要一个包含易失性项目的数组,但找不到办法。

private volatile T[] _arr;

这意味着 _arr 引用是可变的,但是它不保证 _arr 对象本身内的项目的任何内容。

有没有办法将 _arr 的项目标记为易失性?

谢谢。

编辑:

以下代码根据 binarycoder 的答案构建。这段代码可以线程安全使用吗?

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; }
    }
}
4

4 回答 4

11

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

了解volatile关键字在幕后工作是有用的,使用Thread.MemoryBarrier. 你可以写:

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

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

请注意,volatileMemoryBarrier都是很容易出错的高级技术。例如,请参阅如何理解读取内存屏障和易失性。通常,您最好使用更高级别的构造,例如lock, Monitor,ReaderWriterLockSlim等。

于 2009-12-05T17:05:46.043 回答
4

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

Volatile从 .NET 4.5 开始可用。它允许读取/写入字段、数组元素、ref参数、指针。

于 2016-07-15T15:31:23.230 回答
2

我不认为你可以

你不能,volatile被定义为字段修饰符(ECMA 334)。

而且我认为它也不会完成您想要的。
考虑:

 private T[] _arr;

 volatile T v;
 ....  v = _arr[x];
 ....  _arr[x] = v;
于 2009-12-05T16:54:32.527 回答
2

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

struct VolatileBoolean {
    public volatile Boolean Value;
}

VolatileBoolean[] arrayOfVolatileBooleans;
public void SomeMethod() {
    if (arrayOfVolatileBooleans[4].Value)
        DoSomething();
}
于 2013-03-22T15:29:53.423 回答