Dan*_*Tao 15 .net double thread-safety
更新:我在Eric Lippert对另一个问题的回答中偶然发现了这个问题(他引用了这个规范):
其他类型的读写,包括long,ulong,double和decimal,以及用户定义的类型,不保证是原子的.
好了,阅读double
是不是原子.这意味着可以在读取中间修改该值,对吧?那么如何以double
原子方式读取值?
我注意到有一种价值Interlocked.Read
方法long
.这对我来说很有意义,因为读取64位值必须需要两个步骤,因此就像其他所有非原子动作一样受到竞争条件的影响.
但目前还没有Interlocked.Read
对double
价值观,即使System.Double
是一个64位的值.
我在我的程序中看到一些奇怪的行为,我的GUI double
在文本框中显示,而double
其他线程也经常更新,在大多数时间显示正确的值(在200.0附近),然后偶尔随机显示错误值(如-0.08).
也许这是一个线程问题,或者也许是其他问题.但首先我想缩小可能性.那么:正在阅读double
线程安全吗?
Eri*_*ert 17
正在阅读双线程安全?
不,正如规范所说
其他类型的读写,包括long,ulong,double和decimal,以及用户定义的类型,不保证是原子的.
继续.
这意味着可以在读取中间修改该值,对吧?
是.
那么如何原子地读取双值?
你可以在每次访问可变变量时锁定.
还有一个你没有问过的问题,但经常被问到是你问题的后续问题:
使字段"易变"会使其读/写原子吗?
不.制作double类型的volatile字段是不合法的.
小智 6
像这样使用Interlocked.Exchange
OR Interlocked.CompareExchange
进行原子读取.
Interlocked.Exchange(ref somevariable, somevariable)
它返回原始值.
如果你想避免写作使用compareExchange
.
Interlocked.CompareExchange(ref somevariable, somevalue, somevalue);
如果变量等于第三个参数,它将用第二个参数替换变量,并返回原始值.通过在两个点中使用相同的值(例如,零),它保证变量的值不被改变.