.NET团队决定在Interlocked.Exchange操作中不支持布尔值是否有一些实际原因?
其中一个用法示例是,当您要保证某些代码只执行一次并且您希望使用布尔标志时。
答案 0 :(得分:58)
是的,有充分的理由。 Interlocked方法的实现需要处理器级别的低级支持。例如,请参阅this answer。当您定义一个与架构无关的框架时,这就是一个问题。
对于本机处理器字大小的一小部分的数据类型,实现Interlocked类支持的低锁技术是很困难的。 10年多以前流行的用于cpu设计的RISC方法强烈劝阻它。操作数大小和本机内存总线宽度之间的不匹配使得它很难实现。英特尔的x86架构仍然在你的腿上的一个原因是,已经30年没有采取捷径。有关RISC的更多背景信息,请参见wikipedia article。
答案 1 :(得分:15)
没有回答这个问题,但作为一种解决方法,你可以像C一样使用int而不是bool。
int m_IsFirstTime = 1; // 1 means true 0 means false.
void SomeMethod()
{
if (1 == Interlocked.Exchange(ref m_IsFirstTime , 0))
// Do something for the first time.
else
// Do something for all other times.
}
P.S。如果有证据表明读取比写入更快,那么Interlocked.CompareExchange对于这种情况可能更好(只有一次第一次,我假设很多非第一次)。
答案 2 :(得分:1)
如果您需要一个简单的解决方案,您可以使用对象字段来设置/获取布尔值。
private object _isRemoved;
public bool isRemoved
{
get
{
object returnVal = Interlocked.CompareExchange(ref _isRemoved, false, null);
return returnVal != null && (bool)returnVal;
}
set
{
Interlocked.Exchange(ref _isRemoved, value);
}
}