Why does Interlocked.Exchange not support Boolean type?

C#.NetMultithreading

C# Problem Overview


Is there some practical reason why the .NET team decided not to support Boolean in Interlocked.Exchange operation?

One of the usage examples is when you want to guarantee that some code is executed only once and you want to use a Boolean flag for that.

C# Solutions


Solution 1 - C#

Yes, there is a good reason. The implementation of the Interlocked methods requires low-level support at the processor level. See this answer for example. That's an issue when you define a framework that's architecture agnostic.

Implementing the low-lock techniques supported by the Interlocked class on data types that are a fraction of the native processor word size is difficult. The RISC approach to cpu design that was popular 10+ years ago discouraged it strongly. The mismatch between operand size and native memory bus width makes it very hard to implement. One reason that Intel's x86 architecture is still on your lap, surviving 30 years already by not taking the shortcuts. More background info on RISC in this wikipedia article.

Solution 2 - C#

Not answering the question, but as a workaround you can just use int instead of bool the way C does.

    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. If there is evidence that read is faster than write then Interlocked.CompareExchange might be better for this case (only one first time and I assume a lot of non first).

Solution 3 - C#

if you need a simple solution, you can use the object field to set/get boolean value.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDennisView Question on Stackoverflow
Solution 1 - C#Hans PassantView Answer on Stackoverflow
Solution 2 - C#ILIA BROUDNOView Answer on Stackoverflow
Solution 3 - C#Mustafa Salih ASLIMView Answer on Stackoverflow