How to block part of a method from other threads?

How can I block part of a method in C # from other threads? I mean if one of the threads was here, then exit ... For example:

if(threads[0].WasHere)
{
   return;
}

      

+3


source to share


3 answers


an effective way is mutual exchange; by setting some token field to a value other than the default at runtime, other threads can check this and exit. For example:

private int hazWorker; // = 0 - put this at the scope you want to protect

      



then

// means: atomically set hazWorker to 1, but only if the old value was 0, and
// tell me what the old value was (and compare that result to 0)
if(Interlocked.CompareExchange(ref hazWorker, 1, 0) != 0) {
    return; // someone else has the conch
}
try {
    // your work here
} finally {
    Interlocked.Exchange(ref hazWorker, 0); // set it back to default   
}

      

+6


source


You can use Monitor.TryEnter for this purpose.

if(!Monitor.TryEnter(someLock))
{
   return;
}
try
{
    //Critical region
}
finally
{
    Monitor.Exit(someLock);
}

      

Or a more reliable way to deal with Rude Thread aborts (suggested by marc in the comments)



bool lockTaken = false;
try
{
    Monitor.TryEnter(someLock, ref lockTaken);
    if (lockTaken)
    {
        //Critical region
    }
}
finally
{
    if(lockTaken) Monitor.Exit(someLock);
}

      

Note that this does not check if it is working threads[0]

, but it does check if any other thread is in the critical region. If so, it exits the method.

+5


source


You can use bool to set it to "false" by default, and then the first stream sets it to "true". And then a piece of code might look like this:

if (!alreadyExecuted)
{
    // ...
    alreadyExecuted = true;
}

      

I would also put the code in a lock to make sure only one thread is executing it at a time (to resolve any possible race conditions) as shown below.

lockVariable is a lock variable and can be of any reference type, for example. object lockVariable = new object ();

lock (lockVariable)
{
    if (!alreadyExecuted)
    {
        // ...
        alreadyExecuted = true;
    }
}

      

+2


source







All Articles