[我正在研究System.Threading.Tasks(.NET标准2.0)中Task的一些实现细节,并且遇到了这段有趣的代码:
internal volatile int m_stateFlags;
...
public bool IsCompleted
{
get
{
int stateFlags = m_stateFlags; // enable inlining of IsCompletedMethod by "cast"ing away the volatiliy
return IsCompletedMethod(stateFlags);
}
}
// Similar to IsCompleted property, but allows for the use of a cached flags value
// rather than reading the volatile m_stateFlags field.
private static bool IsCompletedMethod(int flags)
{
return (flags & TASK_STATE_COMPLETED_MASK) != 0;
}
我从阅读C#参考指南中了解到,存在volatile可以防止编译器/运行时/硬件优化导致对字段的读/写重新排序。为什么在这种特定情况下,将字段分配给变量,以便在读取字段时忽略字段的波动性而将字段指定为volatile?
这似乎是有意的,但意图背后的原因对我来说还不清楚。另外,“抛售”挥发物是否是常见的做法?与绝对要避免的情况相比,在哪种情况下我想这样做?
任何帮助我理解此代码清除器的信息,我们将不胜感激。
谢谢,
volatile
是a syntax sugar of Volatile.Read
and Volatile.Write
。它确保所有CPU都将同时看到相同的数据。
因此,它仅读取volatile变量一次。然后,可以在属性,方法(失去易失性)中多次使用它。因此,看起来它需要对变量进行快照并对其值进行几次计算。
Volatile.Read