首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#中的易挥发场

C#中的易挥发场
EN

Stack Overflow用户
提问于 2011-02-25 03:41:04
回答 4查看 3.8K关注 0票数 11

来自规范10.5.3易失性字段:

易失性字段的类型必须是下列之一:

  • 参考型。
  • 类型字节、字节、短、ushort、int、uint、char、float、bool、System.IntPtr或System.UIntPtr。
  • 一种枚举类型,具有字节、字节、短、ushort、int或uint的枚举基类型。

首先,我想确认我的理解是正确的:我想上述类型可能是不稳定的,因为它们作为一个4字节的单元存储在内存中(对于引用类型,因为它的地址),这保证了读/写操作是原子的。双/long/etc类型不能易失性,因为它们不是原子读/写,因为它们在内存中超过4个字节。我的理解正确吗?

第二,如果第一次猜测是正确的,为什么用户定义的结构中只有一个int字段(或者类似的,4个字节是可以的)不能易失性?理论上它是原子的,对吧?或者仅仅因为不允许所有用户定义的结构(可能超过4个字节)都不允许通过设计来使易失

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-01-14 15:27:14

因此,我想你建议增加以下几点:

  • 一种值类型,仅由一个字段组成,可合法标记为易失性字段。

首先,字段通常是私有的,因此在外部代码中,不应该依赖于某个字段的存在。尽管编译器在访问私有字段时没有问题,但是基于程序员没有适当的方法来影响或检查某个特性并不是一个好主意。

由于字段通常是类型内部实现的一部分,因此可以在引用的程序集中随时更改该字段,但这会使使用该类型的C#代码片段成为非法。

这一理论和实践上的原因意味着,唯一可行的方法是为值类型引入一个volatile修饰符,以确保上面指定的点仍然有效。但是,由于唯一受益于此修饰符的类型是具有单个字段的值类型,因此此特性在列表中可能并不是很高。

票数 1
EN

Stack Overflow用户

发布于 2011-02-25 04:16:32

我认为这是因为struct是一个值类型,它不是规范中列出的类型之一。值得注意的是,引用类型可以是一个易失性字段。因此,它可以通过用户定义的类来完成。这可能不符合您的理论,即上述类型是不稳定的,因为它们可以存储在4个字节(或者可能不是)。

票数 0
EN

Stack Overflow用户

发布于 2012-11-02 01:06:50

这是一个有教养的猜测.如果我错了,请不要把我打得太厉害!

挥发性文件指出:

易失性修饰符通常用于由多个线程访问的字段,而不使用lock语句序列化访问。

这意味着易失性字段的设计意图的一部分是实现无锁的多线程访问。

结构的成员可以独立于其他成员进行更新。因此,为了写入新的结构值,其中只有一部分被更改,必须读取旧的值。因此,写入不能保证只需要一个内存操作。这意味着,为了在多线程环境中可靠地更新结构,需要某种类型的锁定或其他线程同步。在没有同步的情况下,从多个线程更新多个成员很快就会导致违反直觉的结果,如果不是技术上的破坏的话:要使结构易失性就会将一个非原子对象标记为原子可更新的对象。

此外,只有一些结构可能是易失性的--那些大小为4字节的结构。确定大小的代码--结构定义--可能位于程序的一个完全独立的部分,与将字段定义为易失性的部分完全不同。这可能会使人感到困惑,因为更新结构的定义会产生意想不到的后果。

因此,虽然技术上可能允许某些结构不稳定,但正确使用的警告将非常复杂,其缺点将大于好处。

我推荐的解决方法是将4字节结构存储为4字节基类型,并实现静态转换方法,以便在每次要使用该字段时使用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5113355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档