What is the threading class if I just want to check and set the flag in thread safe mode?

I just want to make a simple, albeit thread-safe, logical test (and install) like this:

if(myBoolean==false) //should not lock/wait! { myBoolean=true; ..... } else { .... } 

I reviewed the following (although it may be wrong, so please correct me where I misunderstood)

  • using the Lock {if (myBoolean) ...} construct, this seems like a way to overdo it. And he also blocks the flow while he waits for the lock to become free. I do not want it.
  • The AutoResetEvent class has the concept of a logical state, but it is used to signal the next thread that is waiting. Therefore it doesn't matter in my case
  • A semaphore class has the concept of a reference counter (perhaps to reduce the amount of access to a resource?). So probably not what I need.
  • Class mutex. As I understand it, this is the same principle as the Lock primitive

Does anyone have an idea what is a class / construct to do this in an efficient way?

+4
source share
6 answers
+8
source

The answer ( Intelocked.CompareExchange ) is already specified, but here is my usage example:

 private int _isDisposing; public bool IsDisposing { get { return this._isDisposing != 0; } } public void Dispose() { // Side note: I may want to `return` instead of `throw` if (Interlocked.CompareExchange(ref _isDisposing, 1, 0) != 0) throw new InvalidOperationException("Dispose was recursively called."); try { Dispose(true); GC.SuppressFinalize(this); } finally { _isDisposing = 0; } } 
+6
source

Your question is somewhat controversial, but you're probably looking for the Interlocked class.

EDIT : You are looking for Interlocked.CompareExchange .

+2
source

In order to have a safe thread test and establish an operation, the code must block other threads. To avoid blocking, you can use the test-and-test-and-set pattern:

 if (something) { lock(_sync) { if (something) { something = false; ... } } } 

A second test is needed to ensure that another thread has not changed the value between the first test and the lock.

+1
source

For the "Test and Add" collections, I use

  /// <summary> /// If h contains v then return true, else add v to h and return false. /// Thread safe on h. /// </summary> /// <param name="h"></param> /// <param name="v"></param> /// <returns></returns> bool TestAndAdd(HashSet<string> h, string v) { lock(h) { if(h.Contains(v)) { return true; } h.Add(v); return false; } } 

Then I can check and install how ..

  if (!TestAndAdd(usedCodes, mc.code)) 
+1
source

I had the same problem many times, and I donโ€™t think I could keep in mind that the last argument to Interlocked.CompareAndChange () is a comparison of and. Here is what I came up with.

 using System.Threading; public class AtomicFlag { public const int SETVALUE = 1; public const int RESETVALUE = 0; /// <summary> /// Represents the current state of the flag. /// 0 means false (or reset). /// 1 means true (or set). /// </summary> private int Value; /// <summary> /// Creates an atomicflag with the specified default value. /// </summary> /// <param name="initialValue">AtomicFlag.SETVALUE or /// AtomicFlag.RESETVALUE. Defaults to RESETVALUE.</param> public AtomicFlag(int initialValue = RESETVALUE) { Guard.AgainstUnsupportedValues<int>(initialValue, "initialValue", new int[] { SETVALUE, RESETVALUE }); Value = initialValue; } public void Set() { Value = SETVALUE; } public void Reset() { Value = RESETVALUE; } public bool TestAndSet() { // Use Interlocked to test if the current value is RESETVALUE, // return true and set value to SETVALUE. // // From Interlocked.CompareExchange help: // public static int CompareExchange( // ref int location1, // int value, // int comparand // ) // where // location1: The destination, whose value is compared with // comparand and possibly replaced. // value: The value that replaces the destination value if the // comparison results in equality. // comparand: The value that is compared to the value at // location1. return (RESETVALUE == Interlocked.CompareExchange( ref Value, SETVALUE, RESETVALUE)); } public bool TestAndReset() { // If the current value is SETVALUE, return true and change value // to RESETVALUE. return (SETVALUE == Interlocked.CompareExchange(ref Value, RESETVALUE, SETVALUE)); } } 
0
source

All Articles