Vladislav
Vladislav

Reputation: 218

How to lock a part of method from another threads?

How can i lock a part of method in c# from another threads? I mean if one of threads was here, then exit... For example:

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

Upvotes: 3

Views: 160

Answers (3)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73452

You can use Monitor.TryEnter for this purpose.

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

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

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

Note that this doesn't checks for threads[0] still working, rather it checks whether any other thread is in Critical region. If so, it exits the method.

Upvotes: 5

Marc Gravell
Marc Gravell

Reputation: 1062745

an effective way is with an interlocked exchange; by setting some token field to a non-default value during the work, the 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   
}

Upvotes: 6

msporek
msporek

Reputation: 1197

You can use a bool value - assign it "false" on default, and then the first of the threads sets it to "true". And then the piece of code could look like this:

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

I would also put the code in a lock to make sure only one thread executes it at time (to deal with any possible race conditions), like below.

The lockVariable is a locker variable and it can be of any reference type, ex. object lockVariable = new object();

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

Upvotes: 2

Related Questions