Reputation: 218
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
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
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
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