C#volatile双

因为只有引用类型和一些原语(包括float,但不是double,我不确定原因,我很高兴听到原因)可以声明为volatile,如果我在类中包装double然后声明它作为volatile(如下所示),double属性是’read write’线程安全,就像任何其他volatile一样,还是我还应该看看锁定?

public class MyThreadedClass { volatile VolatileDouble voldub; } public class VolatileDouble { public double Double { get; set; } } 

double不能声明为volatile的原因:它是64位,这使得它超过了x86上的字大小,如果我没记错的话,这会阻止它在CLI中被声明为volatile。

根据您当前的答案,只有参考被视为易失性。 这意味着内存模型将确保它始终使用最新的引用,但它仍然可以使用陈旧值。

如果我是你,我会使用锁定,但另一种方法是使用Interlocked.ReadInterlocked.Exchange作用于long,与BitConverter.Int64BitsToDoubleBitConverter.DoubleToInt64Bits一起使用。 您可以将其封装在VolatileDouble结构中。 (我可能会把它变成一个结构而不是一个类。)

要像上面这样工作,你需要让它不可变(没有setter) – 为方便起见,可能还有一些隐式转换运算符。 否则,人们可以在不更改(volatile)引用的情况下更改值。

 public class MyThreadedClass { volatile Box volDouble = 123.45; } public class Box 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 box) { return box.value; } public static implicit operator T?(Box box) { return box == null ? new T?() : new T?(box.value); } public static implicit operator Box(T value) { return new Box(value); } public static implicit operator Box(T? value) { return value.HasValue ? new Box(value.Value) : null; } } 

除此之外 – 锁定将是最好的选择。

您只是声明引用是volatile而不是实例,因此无法解决问题。

易变文档有些误导……

当msdn文档说它使用最新的值是什么意思??? 我确信在一个简单的值中,这不会导致混淆,但是参考如何,就像Brian Rasmussen,你只是在讨论ref而不是实际的实例(因此也就是有趣的数据)。

从我的观点来看,使用volatile不是一个好主意,我会去锁定,无论如何这篇文章可能对你有所帮助: http : //www.bluebytesoftware.com/blog/PermaLink,guid,dd3aff8a-7f8d-4de6- a2e7-d199662b68f4.aspx