2009-12-05 6 views
9

Ich brauche ein Array mit volatilen Elementen und kann keinen Weg finden, dies zu tun. DieseC# flüchtige Array-Elemente?

private volatile T[] _arr; 

bedeutet, dass die _arr Referenz flüchtig ist, aber es ist nichts garantiert über die Elemente im Inneren des _arr Objekt selbst.

Gibt es eine Möglichkeit, die Elemente des _arr als flüchtig zu markieren?

Danke.

EDIT:

Der folgende Code gebaut nach binarycoder Antwort. Ist dieser Code threadsicher?

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

Diese Frage braucht mehr Liebe. –

Antwort

7

Da es möglich ist, Array-Elemente durch Verweis übergeben, Sie Thread.VolatileRead und Thread.VolatileWrite verwenden können.

Es ist nützlich zu verstehen, dass das Schlüsselwort volatile hinter den Kulissen funktioniert, indem Thread.MemoryBarrier verwendet wird. Man könnte schreiben:

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

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

Beachten Sie, dass volatile und MemoryBarrier fortgeschrittene Techniken, die beide leicht zu bekommen sind falsch. Siehe zum Beispiel How do I Understand Read Memory Barriers and Volatile. Normalerweise sind Sie besser mit Konstrukten höherer Ebene wie lock, Monitor, ReaderWriterLockSlim und anderen.

+0

IIRC, dann strikt das Schlüsselwort 'volatile' nur eine Lese- oder Schreibbarriere, während' Thread.MemoryBarrier() 'eine volle Barriere hat. Das obige ist daher etwas schwerer als die äquivalente Verwendung von "flüchtig", sogar bevor wir in Betracht ziehen, dass es sich um einen Methodenaufruf handelt. Es ist immer noch das Beste, was wir tun können (und wie Sie sagen, die aktuelle Implementierung von 'VolatileRead()' und 'VolatileWrite()'). –

1

Ich glaube nicht, dass Sie

Sie nicht können, volatile als Feld Modifikator definiert (ECMA 334).

Und ich glaube nicht, dass es auch erreichen wird, was Sie wollen.
Bedenken Sie:

private T[] _arr; 

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

machte ich eine kleine Struktur, die Dinge sauber zu halten und OO

struct VolatileBoolean { 
    public volatile Boolean Value; 
} 

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

Verwenden Volatile.Read(ref array[index]) und Volatile.Write(ref array[index], value) hilft.

Die Klasse Volatile ist seit .NET 4.5 verfügbar. Es ermöglicht das Lesen/Schreiben von/zu Feldern, Array-Elementen, ref Parametern, Zeigern.

Verwandte Themen