为什么Interlocked.Exchange不支持布尔类型?

时间:2011-05-28 22:34:50

标签: c# .net multithreading

.NET团队决定在Interlocked.Exchange操作中不支持布尔值是否有一些实际原因?

其中一个用法示例是,当您要保证某些代码只执行一次并且您希望使用布尔标志时。

3 个答案:

答案 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);
        }
    }