Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the threading class if I just want to test and set a flag in a threadsafe manner?

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?

like image 232
Toad Avatar asked Jan 15 '10 15:01

Toad


2 Answers

Consider Interlocked.CompareExchange.

like image 153
John Saunders Avatar answered Sep 21 '22 02:09

John Saunders


The answer (Interlocked.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;
    }
}
like image 24
Sam Harwell Avatar answered Sep 19 '22 02:09

Sam Harwell