Почему Interlocked.Exchange не поддерживает тип Boolean?

Есть ли какая-то практическая причина, почему команда .NET решила не поддерживать логическую операцию в Interlocked.Exchange?

Один из примеров использования - это когда вы хотите гарантировать, что какой-то код выполняется только один раз, и вы хотите использовать для этого логический флаг.

Ответ 1

Да, есть веская причина. Для реализации Interlocked-методов требуется поддержка низкого уровня на уровне процессора. Например, см. этот ответ. Это проблема, когда вы определяете структуру, которая не обладает агностикой архитектуры.

Реализация технологий с низким уровнем блокировки, поддерживаемых классом Interlocked, для типов данных, которые являются частью размера слова процессора, затруднительна. Подход RISC к дизайну процессора, который был популярен еще 10 лет назад, сильно его не поощрял. Несоответствие между размером операнда и шириной шины собственной памяти делает его очень трудным для реализации. Одна из причин того, что архитектура Intel x86 все еще находится на вашем коленях, выживание уже 30 лет, не используя ярлыки. Дополнительная информация о RISC в этой статье в википедии.

Ответ 2

Не отвечая на вопрос, но в качестве обходного пути вы можете просто использовать int вместо bool, как это делает C.

    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 может быть лучше для этого случая (только один раз, и я принимаю много не первых).