2009-12-05 17 views
9

Ho bisogno di un array con elementi volatili e non riesco a trovare un modo per farlo.Elementi di array C# volatile?

private volatile T[] _arr; 

Ciò significa che il riferimento _arr è volatile, ma non garantisce nulla circa gli elementi all'interno dell'oggetto _arr stessa.

Esiste un modo per segnalare articoli del _arr come volatile?

Grazie.

EDIT:

Il seguente codice costruito secondo la risposta di binarycoder. È sicuro utilizzare questo codice thread-safe?

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; } 
    } 
} 
+2

Questa domanda ha bisogno di più amore. –

risposta

7

Poiché è possibile passare elementi di matrice per riferimento, si può usare Thread.VolatileRead e Thread.VolatileWrite.

È utile comprendere che la parola chiave volatile opera dietro le quinte utilizzando Thread.MemoryBarrier. Si potrebbe scrivere:

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

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

noti che volatile e MemoryBarrier sono tecniche avanzate che sono sia facile da sbagliare. Ad esempio, vedere How do I Understand Read Memory Barriers and Volatile. Di solito si sta meglio con i costrutti di livello superiore, come lock, Monitor, ReaderWriterLockSlim, e altri.

+0

IIRC, quindi strettamente, la parola chiave 'volatile' comporta solo una barriera di lettura o scrittura, a seconda dei casi, mentre 'Thread.MemoryBarrier()' ha una barriera completa. Quanto sopra pertanto è leggermente più pesante dell'equivalente uso di 'volatile' ancor prima che consideriamo che riguarda una chiamata al metodo. È ancora il meglio che possiamo fare (e come dici tu, l'attuale implementazione di 'VolatileRead()' e 'VolatileWrite()'). –

1

Non credo che si può

Non è possibile, volatile è definito come un campo di modifica (ECMA 334).

E io non credo che porterà a compimento ciò che si vuole sia.
consideri:

private T[] _arr; 

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

Ho fatto un po 'struct che aiuta a mantenere le cose pulite e OO

struct VolatileBoolean { 
    public volatile Boolean Value; 
} 

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

Usa Volatile.Read(ref array[index]) e Volatile.Write(ref array[index], value).

Classe Volatile è disponibile dal .NET 4.5. Permette di leggere/scrivere da/a campi, elementi di array, parametri ref, puntatori.