Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Interlocked.CompareExchange() operation on a bool value?

I have two questions:

  1. Is there a need to use Interlocked class for accessing boolean values? Isn't a read or a write to a boolean value atomic by default?

  2. I tried using Interlocked.CompareExchange on a boolean and got the following error:

     bool value = true;  Interlocked.CompareExchange<bool>(ref value, false, true); 

    Error: The type 'bool' must be a reference type in order to use it as parameter 'T' in the generic type or method 'System.Threading.Interlocked.CompareExchange(ref T, T, T)'

How do I go about solving this problem?

like image 569
Bhargav Mangipudi Avatar asked Jul 12 '11 07:07

Bhargav Mangipudi


People also ask

What is Interlocked CompareExchange?

Compares two platform-specific handles or pointers for equality and, if they are equal, replaces the first one. CompareExchange(UInt64, UInt64, UInt64) Compares two 64-bit unsigned integers for equality and, if they are equal, replaces the first value.

Is Boolean thread safe C#?

None of these are thread-safe. The thread that calls the getter will always read a stale value. How stale it is depends on the processor and the optimizer.

What is interlocked in C#?

This C# class helps with threading. It safely changes the value of a shared variable from multiple threads. It is part of System.

Is bool Atomic C#?

Yes. Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types. as found in C# Language Spec.


1 Answers

  1. Reading or writing boolean values separately is atomic, but "compare and exchange" does both reading and writing to the same address, which means that entire transaction is not atomic. If multiple threads can write to this same location, you need to make the entire transaction atomic, by using the Interlocked class.

  2. public static T CompareExchange<T>(ref T a, T b, T c)) where T : class overload can only be used with reference types (note the where T : class clause at the end). Instead of a boolean value, you can use the CompareExchange(Int32, Int32, Int32) overload, and switch the boolean with an Int32.

    Alternatively, if you want to keep your variables of boolean type, you can use the lock method to ensure thread safety. This would be a slightly slower solution, but depending on your performance requirements, this might be still the preferred way.

like image 118
Groo Avatar answered Oct 05 '22 22:10

Groo