2009-12-05 10 views
9

J'ai besoin d'un tableau avec des éléments volatiles, et je ne trouve pas le moyen de le faire.C# éléments de tableau volatils?

private volatile T[] _arr; 

Cela signifie que la référence _arr est volatile, mais il ne garantit rien sur les éléments dans l'objet _arr lui-même.

Y at-il un moyen de marquer les éléments de _arr comme volatils?

Merci.

EDIT:

Le code suivant construit selon la réponse de binarycoder. Ce code est-il compatible avec les threads?

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

Cette question a besoin de plus d'amour. –

Répondre

7

Comme il est possible de passer des éléments de tableau par référence, vous pouvez utiliser Thread.VolatileRead et Thread.VolatileWrite.

Il est utile de comprendre que le mot-clé volatile fonctionne derrière la scène en utilisant Thread.MemoryBarrier. Vous pouvez écrire:

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

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

Notez que volatile et MemoryBarrier sont des techniques avancées qui sont à la fois facile de se tromper. Par exemple, voir How do I Understand Read Memory Barriers and Volatile. Habituellement, vous êtes mieux avec des constructions de niveau supérieur tels que lock, Monitor, ReaderWriterLockSlim, et d'autres.

+0

IIRC, alors strictement, le mot-clé 'volatile' implique seulement une barrière de lecture ou d'écriture comme approprié, alors que' Thread.MemoryBarrier() 'a une barrière complète. Ce qui précède est donc légèrement plus lourd que l'utilisation équivalente de «volatile» avant même que nous considérons qu'il implique un appel de méthode. C'est toujours le meilleur que nous pouvons faire (et comme vous le dites, l'implémentation actuelle de 'VolatileRead()' et 'VolatileWrite()'). –

1

Je ne pense pas que vous pouvez

Vous ne pouvez pas, volatile est défini comme un champ modificateur (ECMA 334).

Et je ne pense pas que cela va accomplir ce que vous voulez non plus.
Tenir compte:

private T[] _arr; 

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

J'ai fait un peu struct qui aide à garder les choses propres et OO

struct VolatileBoolean { 
    public volatile Boolean Value; 
} 

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

Utilisez Volatile.Read(ref array[index]) et Volatile.Write(ref array[index], value). La classe Volatile est disponible depuis .NET 4.5. Il permet de lire/écrire depuis/vers des champs, des éléments de tableau, des paramètres ref, des pointeurs.