2009-12-05 49 views
9

我需要一个包含易失性项目的数组,并且无法找到这样做的方法。C#volatile数组项?

private volatile T[] _arr; 

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

有什么办法可以将_arr的Items标记为volatile吗?

谢谢。

编辑:

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

这个问题需要更多的爱。 – 2012-04-27 18:36:18

回答

7

由于有可能通过引用传递数组元素,可以使用Thread.VolatileReadThread.VolatileWrite

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

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

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

注意volatileMemoryBarrier是先进的技术,既容易出错。例如,请参阅How do I Understand Read Memory Barriers and Volatile。通常情况下,你最好使用更高级别的结构,如lock,Monitor,ReaderWriterLockSlim等。

+0

IIRC,严格来说,'volatile'关键字只需要一个读或写障碍,而'Thread.MemoryBarrier()'完全有障碍。因此,即使在我们认为它涉及方法调用之前,上面的内容稍微比“volatile”的等同使用稍重。它仍然是我们可以做的最好的(正如你所说的,当前实现'VolatileRead()'和'VolatileWrite()')。 – 2011-11-08 20:29:50

1

我不认为你可以

你不能,volatile被定义为一个场的改性剂(ECMA 334)。

而且我不认为它会达到你想要的。
考虑:

private T[] _arr; 

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

我做了一个小结构,有助于保持干净的东西和OO

struct VolatileBoolean { 
    public volatile Boolean Value; 
} 

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

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

类别Volatile自.NET 4.5起可用。它允许读/写字段,数组元素,参数,指针。