C # volatile массив элементов? - PullRequest
       4

C # volatile массив элементов?

13 голосов
/ 05 декабря 2009

Мне нужен массив с изменчивыми элементами, и я не могу найти способ сделать это.

private volatile T[] _arr;

Это означает, что ссылка _arr является изменчивой, однако она ничего не гарантирует относительно элементов внутрисам объект _arr.

Есть ли способ пометить элементы _arr как изменчивые?

Спасибо.

РЕДАКТИРОВАТЬ:

Следующий код построен в соответствии с ответом бинарного кодера.Этот код безопасен для многопоточности?

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 ]

7 голосов
/ 05 декабря 2009

Поскольку элементы массива можно передавать по ссылке, вы можете использовать Thread.VolatileRead и Thread.VolatileWrite.

Полезно понимать, что ключевое слово volatile работает за кулисами, используя Thread.MemoryBarrier. Вы могли бы написать:

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

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

Обратите внимание, что volatile и MemoryBarrier являются продвинутыми техниками, которые легко ошибиться. Например, см. Как понимать барьеры чтения памяти и энергозависимость . Обычно вам лучше использовать конструкции более высокого уровня, такие как lock, Monitor, ReaderWriterLockSlim и другие.

1 голос
/ 15 июля 2016

Используйте Volatile.Read(ref array[index]) и Volatile.Write(ref array[index], value).

Класс Volatile доступен с версии .NET 4.5. Позволяет читать / записывать из / в поля, элементы массива, ref параметры, указатели.

1 голос
/ 22 марта 2013

Я сделал небольшую структуру, которая помогает содержать вещи в чистоте и OO

struct VolatileBoolean {
    public volatile Boolean Value;
}

VolatileBoolean[] arrayOfVolatileBooleans;
public void SomeMethod() {
    if (arrayOfVolatileBooleans[4].Value)
        DoSomething();
}
1 голос
/ 05 декабря 2009

Я не думаю, что вы можете

Вы не можете, volatile определяется как модификатор поля (ECMA 334).

И я не думаю, что это достигнет того, чего вы хотите.
Рассмотрим:

 private T[] _arr;

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