2009-02-10 54 views
10

由於只有引用類型和一些原語(包括浮動,但不會增加一倍,我不知道爲什麼,我很高興聽到的原因所在)可以聲明爲揮發,如果我換一個雙在一個類然後聲明它爲volatile(如下),將雙線屬性'讀寫'線程安全的任何其他易失性,或者我應該仍然在鎖定?C#揮發性雙

public class MyThreadedClass 
{ 
    volatile VolatileDouble voldub; 
} 

public class VolatileDouble 
{ 
    public double Double { get; set; } 
} 

回答

16

之所以雙重不能被聲明爲volatile:它是64位的,這使得不是x86字的大小,以防止它被宣佈爲CLI揮發,如果我沒記錯的話更多。

以您目前的答案,只有參考被視爲是揮發性的。這意味着內存模型將確保它始終使用最新的引用,但它仍然可以使用陳舊的值。

我會用,如果我是你鎖定去,但一個替代方案是使用作用於多頭Interlocked.ReadInterlocked.Exchange,連同BitConverter.Int64BitsToDoubleBitConverter.DoubleToInt64Bits。您可以將其封裝在VolatileDouble結構中。 (我可能會使其成爲一個結構,而不是一類。)

+0

類。感謝確認 – johnc 2009-02-10 10:48:48

+0

如果他確定VolatileDouble是不可改變的,他不應該有問題,對嗎? – 2009-02-10 10:51:33

+0

也感謝爲互鎖和BitConverter建議,引發了思想 – johnc 2009-02-10 10:57:34

5

爲了按上述方式工作,你需要有它不可變的(沒有setter) - 也許一些隱式轉換操作符提供方便。否則,人們可以在不更改(易失性)引用的情況下更改該值。

public class MyThreadedClass 
{ 
    volatile Box<double> volDouble = 123.45; 
} 

public class Box<T> where T : struct 
{ 
    private readonly T value; 
    public Box(T value) { this.value = value; } 
    public T Value {get {return value;}} 

    // explicit as nulls are a problem... 
    public static explicit operator T(Box<T> box) { 
     return box.value; } 
    public static implicit operator T?(Box<T> box) { 
     return box == null ? new T?() : new T?(box.value); } 
    public static implicit operator Box<T>(T value) { 
     return new Box<T>(value); } 
    public static implicit operator Box<T>(T? value) { 
     return value.HasValue ? new Box<T>(value.Value) : null; } 
} 

除此之外 - 鎖定將是最好的選擇。

3

你只是宣稱引用是不揮發的情況下,這樣就不會解決問題。

0

揮發性文檔是一些如何誤導...

當MSDN文檔說,它採用了目前最新的價值是什麼意思???我敢肯定,在一個簡單的值中,這不會導致混淆,但是參考如何,正如Brian Rasmussen所談論的那樣,不是實際的實例(以及有趣的數據)。

從我的使用揮發性的觀點是不是一個好主意,我會去鎖,反正這篇文章可以幫助你:懷疑,只有參考是揮發性的,因此這個問題http://www.bluebytesoftware.com/blog/PermaLink,guid,dd3aff8a-7f8d-4de6-a2e7-d199662b68f4.aspx