views:

59

answers:

4

I just want to do a simple, though thread-safe, boolean test (and set) so:

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

I considered the following (although possibly incorrectly, so please correct me where I misunderstood)

  • using the Lock { if(myBoolean)... } construct seems like a overkill way to do it. And, it also locks the thread while it waits for the lock to become free. I don't want this.
  • The AutoResetEvent class does have a concept of a boolean state, but it is used to signal another thread which is waiting. So not relevant in my case
  • Semaphore class has a notion of a reference count (probably to throttle the amount of access to a resource?). So probably not what I'm after.
  • Mutex class. As far as I understood, this is the same principal as the Lock primitive

Anyone have an idea what is the class/construct to do this in an efficient manner?

+2  A: 

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

EDIT: You're looking for Interlocked.CompareExchange.

SLaks
@slaks: I don't know how my question could be any more specific. What is the .net equivalent of the atomic testandset (a well known concurrency pattern). I thought I explained this well.
Toad
Using Interlocked you can do what you call "testandset" in an atomic operation.
winSharp93
thanks for the help! +1
Toad
+3  A: 

Consider Interlocked.CompareExchange.

John Saunders
thanks... I think what I want can be done with this method.
Toad
+1  A: 

To have a thread safe test and set operation the code have to block other threads. To avoid locking uneccesary, you can use the test-and-test-and-set pattern:

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

The second test is needed to be sure that some other thread didn't change the value between the first test and the lock.

Guffa
But since the double test is not atomic, it is still possible the Lock will set my thread in a wait state. I was really hoping for an atomic 'testandset' function.
Toad
Don't you also have to make sure that 'something' is volatile for this to be effective?
SnOrfus
+1  A: 

The answer (Intelocked.CompareExchange) was already given, but here's 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;
    }
}
280Z28
thanks for the usage example (+1)
Toad